Easy-peasy: Nested Model Question

Created on 11 Mar 2020  路  6Comments  路  Source: ctrlplusb/easy-peasy

This is a question not an issue, but I would be glad to get your comments.

If we have to model a one-to-many relation, where both models have specific actions,
let's say:

const childModel = {
  id: "",
  parent: "",
  items: {},
  addItem: action( (state, payload) => {
    state.items[payload.id} = payload;
  ),
  removeItem: action( (state, id) => {
    delete state.items[id};
  )
};

const parentModel = {
  id: "",
 children: {},
 addChild: action( (state, payload) => {
   state.children[payload.id] = {...childModel, ...payload, parent:state.id}; // :)
 })
};

This doesn't work as it is. I am using something like this:

const parentModel = {
  id: "",
 children: {},
 addChild: action( (state, payload) => {
   state.children[payload.id] = createStore( {...childModel, ...payload, parent:state.id} );
 })
};

That allows me to write things like:

  parent.children[id].addItem({id: 1, name: "pees"})

which is nice!

However the state tree has to be computed:

Object.values(parent.children).map(child => child.getState())

which feels wrong :/

If anyone has a similar issue solved more elegantly I would love to see it!

Thank you!

question

Most helpful comment

Hmmmm, you certainly have me thinking. I will continue to do so and if I think of anything interesting I'll feed back to you here. 馃檹

All 6 comments

Hey @andreiQuant

I apologise but I am not sure I fully understand what you are trying to do, and what the problem is.

It would be really helpful for me if you could create a minimal example in CodeSandbox which illustrates the problem. 馃憤

Hey there @ctrlplusb!

Thanks for taking the time to read my thing :)

I was purely asking for an advice on how one can address the case of a model that has a collection of other models that are added at run time.

The problem is that child models added to state are not being treated as models but as objects and the state of the main model serves the state of the childs along with their actions.

I will create an example :)

Thank you!

Hey @ctrlplusb,

Here is a sample showing the difference between nested models added at "design time" and those added at "run-time" :

https://codesandbox.io/s/easy-peasy-nested-1d1rw

Hi @andreiQuant

Dynamically adding models containing actions won't be a case we will cover. My recommendation is that you instead keep the dynamically added model as pure state rather, and then lift the addToy action up a level. Allow it to receive an index / identifier of which state should be updated.

For example;

export const child = (id, parent) => ({
  id: id,
  parent: parent,
  toys: {},
  ids: [],
});

export const parentModel = {
  count: 2,
  id: 1,
  children: {
    1: child(1, 1),
    2: child(2, 1)
  },
  addChild: action((state, payload) => {
    const id = (state.count += 1);
    state.children[state.count] = child(id, state.id);
  }),
  addToyToChild: action((state, payload) => {
    const { childId, toy } = payload;
    const child = state.children[childId];
    const toyId = child.ids.length === 0 ? 0 : Math.max(...child.ids) + 1;
    child.toys[toyId] = { ...toy, id: toyId };
    child.ids.push(toyId);
  })
};
const store = createStore({ parent: parentModel });

Thank you @ctrlplusb for taking the time to review my question.
I got your point and I already solved it like this :)

However the original issue, dynamic build model, will be there even for simple cases not only for collections.

If you want to add an action or a property of a model at 'run-time' they will not act like those defined at 'design time'.

Thank you!

Hmmmm, you certainly have me thinking. I will continue to do so and if I think of anything interesting I'll feed back to you here. 馃檹

Was this page helpful?
0 / 5 - 0 ratings

Related issues

raul-madrigal picture raul-madrigal  路  3Comments

pitops picture pitops  路  4Comments

jakobmulvad picture jakobmulvad  路  5Comments

gino8080 picture gino8080  路  5Comments

vincentjames501 picture vincentjames501  路  6Comments