mobx-state-tree
mobx-state-tree copied to clipboard
getParent returns undefined
Bug report
- [x] I've checked documentation and searched for existing issues
- [x] I've made sure my project is based on the latest MST version
Sandbox link or minimal reproduction code Sandbox: https://codesandbox.io/s/heuristic-sound-kl7kd Example:
import { types, getParent, isRoot, hasParent } from "mobx-state-tree";
const ChildModel = types.model("Child", {})
.actions(self => ({
afterAttach() {
console.log("Is Root:", isRoot(self)); // false
console.log("Has Parent:", hasParent(self)); // true
console.log("Parent:", getParent(self)); // undefined. Why?
}
}));
export const ParentModel = types.model("Parent", {
child: types.optional(ChildModel, () => ChildModel.create())
});
const parent = ParentModel.create();
Describe the expected behavior
Should be able to retrieve parent instance from child in afterAttach hook. I.e. the logs should show:
Is Root: false
Has Parent: true
Parent: { child: { } }
Describe the observed behavior
Child is not the root and has parent but getParent returns undefined. I.e. the logs show:
Is Root: false
Has Parent: true
Parent: undefined
I think youre not supposed to use the create method inside the model property definitions. Instead, just pass it a valid object for the model you want to create. This works for your example:
export const ParentModel = types.model("Parent", {
child: types.optional(ChildModel, {})
});
@IngoValente Thanks! I don't think the problem is that you're not allowed to invoke the create method of a model inside the definition (especially for a different model). Instead I think your example shows that you have to provide a snapshot of the type instead of an instance of the type, and that is more likely the answer.
I'm running into exactly this problem too.
I'm facing a similar problem.
I met the same problem. and solved it
import { types, getParent, isRoot, hasParent } from "mobx-state-tree";
const ChildModel = types.model("Child", {})
.actions(self => ({
afterAttach() {
console.log("Is Root:", isRoot(self)); // false
console.log("Has Parent:", hasParent(self)); // true
console.log("Parent:", getParent(self)); // ParentModelInstance ,as expected
}
}));
export const ParentModel = types.model("Parent", {
child: types.maybeNull(ChildModel) // don't create child here
})
.actions(self => ({
afterCreate() {
self.child = ChildModel.create({}) // create child after parent creation
}
}))
const parent = ParentModel.create();
I guess when childModel's afterAttach method is called during definning parent model, At this time, parent model has not been created, so you can't get it.
Hey folks - sorry it's been a while with inactivity on this MST issue.
I think that https://github.com/mobxjs/mobx-state-tree/pull/1952 might also be the overall fix here. There are a bunch of issues about these lifecycle hooks.
I'm going to tag this issue to indicate it has a PR to fix already, and hopefully add to the list of issues we can resolve with that PR.
Thanks for all the discussion!
Closing this out because that PR was merged. Please let me know if you still have the same issue on latest MST!