When I retrieve data from webserver, for some reason, I can't tell what kind structure of data will return by server, so I can't define the model exactly.
For instance, I may get data like this:
{ id: 1, config: { a: 1, x: {y:2}, b: {c: [ {d:4}, 5] }...}
I can't predict how many layers is in there, event if I define type like this:
{
config: types.map(
types.union(
types.string,
types.number,
types.array(
types.union(
type.number, type.string
)
),
types.map(types.union(types.string, types.number, types.array(types.union(type.number, type.string)))))
}
...
Firstly, this structure is still not compatible to all structures. Secondly, using type like this, is hard to change value
what I want to do is
this.config.x.y = 3
by this type I defined I have to
this.config.get('x').set('y', 3)
So, I think this is quite usual scenario in the real world, what is the correct way to handle it?
what I want to do is
this.config.x.y = 3
by this type I defined I have to
this.config.get('x').set('y', 3)
That is required, because as you would do using MobX, it can't observe properties if it can't know if they exists or not. Thats why a .get/set is required :)
Dealing with that type structures is hard in typed situations, but can be achieved by declaring a recursive structure of arrays and maps.
https://mattiamanzati.github.io/mobx-state-tree-playground/build/index.html#src=import%20%7B%20types%2C%20unprotect%2C%20resolve%2C%20getType%20%7D%20from%20%22mobx-state-tree%22%0Aimport%20%7B%20inspect%20%7D%20from%20%22mobx-state-tree-playground%22%0A%0Aconst%20Node%20%3D%20types.union(%0A%20%20%20%20%20%20%20%20types.array(types.late(()%20%3D%3E%20Node))%2C%0A%20%20%20%20%20%20%20%20types.map(types.late(()%20%3D%3E%20Node))%2C%0A%20%20%20%20%20%20%20%20types.string%2C%20%0A%20%20%20%20%20%20%20%20types.number%0A%20%20%20%20)%0A%0Aconst%20store%20%3D%20Node.create(%7B%20id%3A%201%2C%20config%3A%20%7B%20a%3A%201%2C%20x%3A%202%7D%7D)%0Ainspect(store)%0Aunprotect(store)%0A%0Astore.set(%22foo%22%2C%20Node.create(%7B%7D))%0Astore.set(%22bar%22%2C%201)%0Astore.get(%22foo%22).set(%22hello%22%2C%20%22world%22)%0A
Feel free to reopen the issue if something is not clear or you have other questions :)
Cool~ I realized there should be recursive structure, and get to know the usage of types.late from your advice, thx.
Helped me as well
Most helpful comment
That is required, because as you would do using MobX, it can't observe properties if it can't know if they exists or not. Thats why a .get/set is required :)
Dealing with that type structures is hard in typed situations, but can be achieved by declaring a recursive structure of arrays and maps.
https://mattiamanzati.github.io/mobx-state-tree-playground/build/index.html#src=import%20%7B%20types%2C%20unprotect%2C%20resolve%2C%20getType%20%7D%20from%20%22mobx-state-tree%22%0Aimport%20%7B%20inspect%20%7D%20from%20%22mobx-state-tree-playground%22%0A%0Aconst%20Node%20%3D%20types.union(%0A%20%20%20%20%20%20%20%20types.array(types.late(()%20%3D%3E%20Node))%2C%0A%20%20%20%20%20%20%20%20types.map(types.late(()%20%3D%3E%20Node))%2C%0A%20%20%20%20%20%20%20%20types.string%2C%20%0A%20%20%20%20%20%20%20%20types.number%0A%20%20%20%20)%0A%0Aconst%20store%20%3D%20Node.create(%7B%20id%3A%201%2C%20config%3A%20%7B%20a%3A%201%2C%20x%3A%202%7D%7D)%0Ainspect(store)%0Aunprotect(store)%0A%0Astore.set(%22foo%22%2C%20Node.create(%7B%7D))%0Astore.set(%22bar%22%2C%201)%0Astore.get(%22foo%22).set(%22hello%22%2C%20%22world%22)%0A
Feel free to reopen the issue if something is not clear or you have other questions :)