I have looked through the mobx-state-tree documents and even the test file https://github.com/mobxjs/mobx-state-tree/blob/master/packages/mobx-state-tree/tests/core/reference-custom.test.ts#L148 to figure out how to populate a reference node from an async source. For instance, user1 is loaded and references user2, but user2 is not in the tree, so go fetch user2 and load it. In the past I had all users being loaded early on, so types.late() worked just fine. But I've stopped loading all the users at the beginning of load time, and instead want only load user data that is being referenced.
Here's an example snippet. I've not actually got this example working in a sandbox, because I'm looking for instructional help from you good folks out there on the logic behind where and how to async-fetch missing nodes. You'll notice that the two users being loaded at store creation reference a third user who's not loaded yet. When MST it populating the tree with the first two users and comes across a reference to an unloaded user id, how do we make it fetch the user and then add it to the users map?
export const User = types
.model("User", {
id: types.identifier,
name: types.string,
friends: types.array(types.late(types.reference(User)))
})
.preProcessSnapshot(snapshot => {
if (snapshot){
return({
id: snapshot.id,
name: snapshot.name,
friends: snapshot.friends
})
}
})
export const UserStore = types
.model("UserStore", {
users: types.map(User),
})
.actions( self => ({
fetchUser: flow(function* (userId) {
let returnThis
try {
returnThis = yield ajaxFetchUser(userId)
self.users.put(returnThis)
} catch (error) {
console.log(error)
}
return self.users.get(returnThis.id)
})
}))
UserStore.create({
users:[{
id: 1,
name: "Justin",
friends: ["2","3"]
},{
id: 2,
name: "Jack",
friends: ["1","3"]
}]
})
const ajaxFetchUser = (userId) => {
// pretend that userId is 3
setTimeout(()=>{
return {
id:3,
name: "John",
friends: ["1","2"]
}
}, 3000)
}
Of course the scripts I'm using are much more complicated than this code, having appropriate map.put and map.get actions.
If anyone could throw some light on this subject, I'd much obliged.