mobx-state-tree
mobx-state-tree copied to clipboard
types.reference is not working on instance creation
Bug report
- [o ] I've checked documentation and searched for existing issues
- [o] I've made sure my project is based on the latest MST version
- [o] Fork this code sandbox or another minimal reproduction.
Sandbox link or minimal reproduction code https://codesandbox.io/s/mobx-state-tree-todolist-forked-cgpms?file=/test..ts
Describe the expected behavior The 'tweet' instance should be used at model creation.
Describe the observed behavior I just copy and paste the document code. But it failed https://github.com/mobxjs/mobx-state-tree/blob/master/README.md#using-a-mst-type-at-design-time
import { types } from "mobx-state-tree"
// Define a couple models
const Author = types.model({
id: types.identifier,
firstName: types.string,
lastName: types.string,
})
const Tweet = types.model({
id: types.identifier,
author: types.reference(Author), // stores just the `id` reference!
body: types.string,
timestamp: types.number,
})
// Define a store just like a model
const RootStore = types.model({
authors: types.array(Author),
tweets: types.array(Tweet),
})
// Instantiate a couple model instances
const jamon = Author.create({
id: "jamon",
firstName: "Jamon",
lastName: "Holmgren",
})
const tweet = Tweet.create({
id: "1",
author: jamon.id, // just the ID needed here
body: "Hello world!",
timestamp: Date.now(),
})
// Now instantiate the store!
const rootStore = RootStore.create({
authors: [jamon],
tweets: [tweet], // ***** Error below *****
})
const tweet: {
id: string;
author: {
id: string;
firstName: string;
lastName: string;
} & NonEmptyObject & IStateTreeNode<IReferenceType<IModelType<{
id: ISimpleType<string>;
firstName: ISimpleType<string>;
lastName: ISimpleType<...>;
}, {}, _NotCustomized, _NotCustomized>>>;
body: string;
timestamp: number;
} & NonEmptyObject & IStateTreeNode<...>
Type '{ id: string; author: { id: string; firstName: string; lastName: string; } & NonEmptyObject & IStateTreeNode<IReferenceType<IModelType<{ id: ISimpleType<string>; firstName: ISimpleType<string>; lastName: ISimpleType<...>; }, {}, _NotCustomized, _NotCustomized>>>; body: string; timestamp: number; } & NonEmptyObject &...' is not assignable to type 'ModelCreationType<ExtractCFromProps<{ id: ISimpleType<string>; author: IReferenceType<IModelType<{ id: ISimpleType<string>; firstName: ISimpleType<string>; lastName: ISimpleType<string>; }, {}, _NotCustomized, _NotCustomized>>; body: ISimpleType<...>; timestamp: ISimpleType<...>; }>>'.
Type '{ id: string; author: { id: string; firstName: string; lastName: string; } & NonEmptyObject & IStateTreeNode<IReferenceType<IModelType<{ id: ISimpleType<string>; firstName: ISimpleType<string>; lastName: ISimpleType<...>; }, {}, _NotCustomized, _NotCustomized>>>; body: string; timestamp: number; } & NonEmptyObject &...' is not assignable to type 'Partial<ExtractCFromProps<{ id: ISimpleType<string>; author: IReferenceType<IModelType<{ id: ISimpleType<string>; firstName: ISimpleType<string>; lastName: ISimpleType<string>; }, {}, _NotCustomized, _NotCustomized>>; body: ISimpleType<...>; timestamp: ISimpleType<...>; }>>'.
Types of property 'author' are incompatible.
Type '{ id: string; firstName: string; lastName: string; } & NonEmptyObject & IStateTreeNode<IReferenceType<IModelType<{ id: ISimpleType<string>; firstName: ISimpleType<string>; lastName: ISimpleType<...>; }, {}, _NotCustomized, _NotCustomized>>>' is not assignable to type 'ReferenceIdentifier'.
Type '{ id: string; firstName: string; lastName: string; } & NonEmptyObject & IStateTreeNode<IReferenceType<IModelType<{ id: ISimpleType<string>; firstName: ISimpleType<string>; lastName: ISimpleType<...>; }, {}, _NotCustomized, _NotCustomized>>>' is not assignable to type 'number'.ts(2322)
Ok. I found answer by myself. Using castToReferenceSnapshot
resolve the error.
But the document needs to be updated.
import { types, castToReferenceSnapshot } from "mobx-state-tree"
...
// Now instantiate the store!
const rootStore = RootStore.create({
authors: [jamon],
tweets: [castToReferenceSnapshot(tweet)],
})
Just curious, why not just pass the POJOs directly to RootStore.create
?
const jamon = {
id: "jamon",
firstName: "Jamon",
lastName: "Holmgren",
};
const tweet = {
id: "1",
author: jamon.id,
body: "Hello world!",
timestamp: Date.now(),
};
const rootStore = RootStore.create({
authors: [jamon],
tweets: [tweet],
});
Hm, yeah, we need to fix this.
Another way to fix this is with makeObservable
, but I don't like that very much either. Doesn't look good in the README, which is what this bit of code is supposed to be (really nice README developer hook).
// Now instantiate the store!
const rootStore = RootStore.create({
authors: [jamon],
tweets: makeObservable([tweet])
});
@MarkLeMerise The reason we aren't using POJOs is we want to show how to create individual instances and then link them together.
Hey @casamia918 - sorry we've still been taking a while on this one. As Jamon said, this is a bug. I'm going to label it as such, along with other tags to help folks prioritize and find issues to work on.
I don't fully understand what to do at this point.
I can't simply copy and paste the example from this repo, since that results in a TS error. The above solutions also result in a TS error...
And looking at the website, all the examples have been removed from the repo as well.
Isn't there a simple, working example like the one in the repo?
Hi @tpotjj - sorry about the confusion. We're in the process of shifting things around. We'll fix those links soon, but for now you can find the old examples over here:
- https://github.com/coolsoftwaretyler/mst-example-bookshop
- https://github.com/coolsoftwaretyler/mst-example-boxes
- https://github.com/coolsoftwaretyler/mst-example-todomvc
- https://github.com/coolsoftwaretyler/mst-example-redux-todomvc
I also have a quick CodeSandbox link that I like to use to start for examples: https://codesandbox.io/s/optimistic-swanson-vjpmyw. I tend to start here because it's more shareable/simpler than the full-fledged examples are.
Most of the code you see in this thread is a known issue, which is why we've marked it as a bug. However, the castToReferenceSnapshot
solution from @casamia918 seems to work. Here's a working CodeSandbox with it: https://codesandbox.io/s/exciting-flower-y5q3p2?file=/src/index.ts
Full code looks like this:
import { castToReferenceSnapshot, types } from "mobx-state-tree";
// Define a couple models
const Author = types.model({
id: types.identifier,
firstName: types.string,
lastName: types.string
});
const Tweet = types.model({
id: types.identifier,
author: types.reference(Author), // stores just the `id` reference!
body: types.string,
timestamp: types.number
});
// Define a store just like a model
const RootStore = types.model({
authors: types.array(Author),
tweets: types.array(Tweet)
});
// Instantiate a couple model instances
const jamon = Author.create({
id: "jamon",
firstName: "Jamon",
lastName: "Holmgren"
});
const tweet = Tweet.create({
id: "1",
author: jamon.id, // just the ID needed here
body: "Hello world!",
timestamp: Date.now()
});
// Now instantiate the store!
const rootStore = RootStore.create({
authors: [jamon],
tweets: [castToReferenceSnapshot(tweet)]
});
It's not particularly ergonomic, but hopefully we'll get someone assigned to this issue in the future to get a better solution in place.
Does that help?