Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional fields #66

Closed
zetoke opened this issue Mar 27, 2017 · 19 comments
Closed

Additional fields #66

zetoke opened this issue Mar 27, 2017 · 19 comments

Comments

@zetoke
Copy link

zetoke commented Mar 27, 2017

Hey, guys!
Thanks a lot for this great lib 👍

Can you clarify one question for me?
I have code:

const Item = createFactory({
  id: types.number,
  name: types.string,
});

const SomeScheme = createFactory({
  items: types.array(Item),
});

const someScheme = SomeScheme(blabla);

const response = await this.fetch('/api/');
someScheme.items.replace(response.data);

Sheme from API:

[
  {
    "id": 2,
    "name": "Name"
  }
]

Everything is ok.

But then at the API backend guys adding new non-breaking (not for us) field.
For example:

[
  {
    "id": 2,
    "name": "Name",
    "description": "Text"
  }
]

And we getting error and stack trace.

How can I avoid/handle this case?

Any solution for ignoring additional fields for the scheme?

@mweststrate
Copy link
Member

Good point, I think that should not be the behavior, I was tinkering about that already.

Currently Item.is({ id: 3, name: "test", stuff: false }) will yield false, I think this behavior should change to mimic how e.g. TypeScript does this, if the required set of attributes is present, there should be a match. What do you think @mattiamanzati ?

@zetoke
Copy link
Author

zetoke commented Mar 27, 2017

How I can help with this issue?

@mweststrate
Copy link
Member

I think this can best and easily be fixed once #65 is done, which features many type system improvements

@mattiamanzati
Copy link
Contributor

Yeah, that should be correct @mwestrate! Btw is it a good thing to silently ingore those properties?

@zetoke
Copy link
Author

zetoke commented Mar 27, 2017

I started an investigation of a problem for myself. Because I need this issue resolved :D
And after some time I wrote this master...zetoke:feature/object-is
The main problem of skipping fields inside isSnapshotValid:

const Factory = createFactory({ a: number });
Factory.is({ b: string })  // true like a Factory.is({})

What do you think about this?

@zetoke
Copy link
Author

zetoke commented Mar 27, 2017

Currently Item.is({ id: 3, name: "test", stuff: false }) will yield false

@mweststrate But Item.is({ id: 4 }) will yield true. Am I right?

@mattiamanzati
Copy link
Contributor

@zetoke Yes indeed, it yields false atm because it checks over the count of keys

@mweststrate
Copy link
Member

@zetoke @mattiamanzati, eh no, should return false imho? name is missing in json but not declared maybe or withDefault

@zetoke
Copy link
Author

zetoke commented Mar 28, 2017

@mweststrate @mattiamanzati but in the latest release (without my modifications) the "same" logic:

Factory = {
  id: number,
  name: string,
}
Factory.is({ id: 5 }) // true

It's bacause .is() is about a snapshot comparsion/validation, not a validation of instance of type (as I understood).

@mattiamanzati
Copy link
Contributor

@zetoke Factory.is({ id: 5, name: "hello", additionalKey: false }) // => false, because the number of keys is > than the allowed

@mweststrate
Copy link
Member

@zetoke I think Factory.is({ id: 5}) -> false, because Factory.create({ id: 5 }) should fail for lacking a name

@mattiamanzati
Copy link
Contributor

@mweststrate Yes indeed

@mweststrate
Copy link
Member

@mattiamanzati btw, should name: string("") be a shorthand for withDefault(string, "") or literal(""). I guess the first right?

@zetoke
Copy link
Author

zetoke commented Mar 28, 2017

@zetoke Factory.is({ id: 5, name: "hello", additionalKey: false }) // => false, because the number of keys is > than the allowed

yep. But if number of keys < keys in snapshot - everything is ok for mobx-state-tree for now. That have been my point.

@zetoke I think Factory.is({ id: 5}) -> false, because Factory.create({ id: 5 }) should fail for lacking a name

Probably. What's about just {} (Factory.is({})) ?

@mattiamanzati
Copy link
Contributor

@mweststrate string("") is the same as doing "", so it will fallback to https://github.com/mobxjs/mobx-state-tree/blob/master/src/types/object.ts#L62-L66 and being a primitive!

So the only correct one is withDefault(string, "")!

With the new syntax that issue will be solved, because it will be string.create("") vs. withDefault(string, "") and that create will let you understand that you are crating an instance instead of passing a type

@zetoke
Copy link
Author

zetoke commented Mar 28, 2017

@zetoke I think Factory.is({ id: 5}) -> false, because Factory.create({ id: 5 }) should fail for lacking a name

@mweststrate The main problem is applySnapshot using .is() as a function for validating snapshot. But this one could be "incremental". Or not?

@mweststrate
Copy link
Member

Imho behavior shoud be:

const Item = createFactory({
  id: types.number,
  name: types.string,
})

Item.is({}) // false, missing name and id
Item.is({ id: 3}) // false, missing name
Item.is({ id: 3, name: ""}) // OK
Item.is({ id: 3, name: "", description: ""}) // OK, but description will be 'lost' upon instantation

createFactory({
  id: types.number,
  name: types.string("")
}).is({ id: 3 }) // OK, name is lacking but has a default

@mattiamanzati
Copy link
Contributor

Only correction is the following

createFactory({
  id: types.number,
  name: types.withDefault(types.string, "")
}).is({ id: 3 }) // OK, name is lacking but has a default

@zetoke
Copy link
Author

zetoke commented Mar 28, 2017

@mweststrate yep, that make sense. I have the same picture in my head.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants