Mobx-state-tree: Question: cloning, identifiers and references

Created on 10 Jul 2017  Â·  11Comments  Â·  Source: mobxjs/mobx-state-tree

Let's say I have a structure like this:

  • Tree

    • Branch

    • Node 1

    • Node 2

where Node 1 has a pointer/reference to Node 2.

I would like to copy the Tree or Branch. I have it set up so that I take the snapshot and update all the unique identifiers. What's the best way to do it so that the copied Node 1 references the copied Node 2 instead of the original Node 2? I also don't really get the point of the clone method if it doesn't update identifiers.

stale

Most helpful comment

https://github.com/mobxjs/mobx-state-tree/pull/1226
After that PR is merged types will expose identifierAttribute, so it would be

const cloneWithAnotherId = (original, anotherId) => getType(original).create({
  ...getSnapshot(original),
  [getType(original).identifierAttribute]: anotherId
}, getEnv(original))

All 11 comments

Clone can't update identifiers because it actually does'nt know how to generate them, they might be uuids, shortid, numbers...who knows! :)
That kind of copy is kinda hard (think of doing that in a relational database with primary keys, would be hard and there is no builtin function for that!)
The only thing I can think of is using "clone" and then using "walk" with getChildType to create new ids and eventually reset references

Yes, I think I was hoping there was an easier way to do it, but will make do! Thanks!

Check out this codesandbox https://codesandbox.io/s/BgM8WJ1m2

Oh boy. I hope you did this because you felt challenged and not because of me :) I think I have my solution, but will also try this out in my codebase and let you know if I run into anything. This is very similar to what I'm doing with copyMap. Although I'm able to make some assumptions about my data structure, so this is definitely more generic/portable. I also like the idea of the finalizers, which may let me do a little less looping.

Maps normally use identifiers as keys if the stored objects have an
identifier, from the top of my head the even enforce that, so probably the
correct behavior is that the clone of map { "17": { id: "17", task: "test"
}} is { "23": { id: "23", task: "test" }}

Op di 11 jul. 2017 om 14:49 schreef Evan Black notifications@github.com:

Oh boy. I hope you did this because you felt challenged and not because of
me :) I think I have my solution, but will also try this out in my codebase
and let you know if I run into anything. This is very similar to what I'm
doing with copyMap. Although I'm able to make some assumptions about my
data structure, so this is definitely more generic/portable. I also like
the idea of the finalizers, which may let me do a little less looping.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/mobxjs/mobx-state-tree/issues/239#issuecomment-314432897,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABvGhCIMoft-gK-OPlkB8ldVrv5---a2ks5sM29ogaJpZM4OTEQJ
.

Yeah, I forgot that MST throws about that! Updated codebox accordingly! :)
https://codesandbox.io/s/yPJZpAqWW

Why was this closed? @evanblack Was it ever resolved? Seems like an actual problem users keep hitting themselves with. Maybe there should be an alternative clone method that will explicitly take in a new value for identifier field. Then it could simply create a new node by merging new identifier onto the snapshot of the given node.

@jayarjo
Why not just

const cloneWithAnotherId = (original, idAttribute, anotherId) => getType(original).create({
  ...getSnapshot(original),
  [idAttribute]: anotherId
}, getEnv(original))

?

Might even add a type.identifierAttribute to the mix so idAttribute is not even needed

https://github.com/mobxjs/mobx-state-tree/pull/1226
After that PR is merged types will expose identifierAttribute, so it would be

const cloneWithAnotherId = (original, anotherId) => getType(original).create({
  ...getSnapshot(original),
  [getType(original).identifierAttribute]: anotherId
}, getEnv(original))

Yeah, that's basically what I advice to do, but could be a decent candidate for a bundled helper, no?

This issue has been automatically marked as stale because it has not had recent activity in the last 10 days. It will be closed in 4 days if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

xgenvn picture xgenvn  Â·  3Comments

tahv0 picture tahv0  Â·  3Comments

lidermanrony picture lidermanrony  Â·  3Comments

elado picture elado  Â·  4Comments

FredyC picture FredyC  Â·  3Comments