ngrx-normalizr icon indicating copy to clipboard operation
ngrx-normalizr copied to clipboard

Updating partial data

Open mecsco opened this issue 6 years ago • 7 comments

If I want to update a certain value (or values) in an object (whether the top-level, a child, or a grandchild), what is the preferred option? If I pass the ID and the name/value of the property and use the Add/Set methods, then any other properties that I'm not passing are removed.

@ngrx/entity (https://github.com/ngrx/platform/blob/master/docs/entity/adapter.md) has update methods which take a Partial<T> to only update the changes - have you considered something similar?

mecsco avatar Dec 04 '17 18:12 mecsco

I did not thought about that yet, but I see that this is a common use case. For not breaking the current behaviour of the AddData action, an UpdateData action might be a simple solution. It can take the entity id, the schema and data to be set. I will give it a try in the develop branch, maybe you can provide some feedback then.

michaelkrone avatar Dec 04 '17 19:12 michaelkrone

Great thanks! I'd be happy to help

mecsco avatar Dec 04 '17 20:12 mecsco

A first work in progress is available in the development branch, if you want to give it a try. You might use the UpdateData or the updateData action creator like this:

// changes is a Partial<Type>
this.store.dispatch(new UpdateData<Type>({id, changes, schema}));
updateData(id, changes);

michaelkrone avatar Dec 04 '17 22:12 michaelkrone

Wow thanks for looking at this so quickly! I've given it a quick test and it looks like it is mostly working for my scenario of updating a single value in a certain object.

However one oddity was in the Redux extension in Chrome - if I've executed an AddData and view the full raw state, I can see the correct values. Once I execute an UpdateData, the diff doesn't show any changes - but if I click back to the previous AddData entry and again view the full raw state, it has the values post-UpdateData. I'm a bit new to this still but does that suggest the reducer is mutating the existing state?

I did experiment a bit with sending some partial objects with nesting and ran into a few issues. There's every chance I'm doing something wrong, but here's a simplified version of what I have:

interface MyParent { id: string; status: string; children: MyChild[]; }
interface MyChild { id: string; status: string; }

new UpdateData<MyParent>({ 
  id: 'abc', 
  changes: { status: 'online', children: [{ id: 'xyz', status: 'offline' }] }, 
  schema: parentSchema })

This results in the 'children' array under entities/MyParent/abc having 2 'xyz' entries. Under entities/MyChild, there is still just one 'xyz' entry but a separate 'id' value has been added to it

As I said, perhaps I'm doing something wrong here - maybe if I wanted this behaviour (which I don't currently need), then I should just use mergeMap in my @ngrx/effect and dispatch multiple UpdateData actions.

mecsco avatar Dec 05 '17 10:12 mecsco

Thank you @mecsco for your feedback. You usage looks absolutely valid, and you are right, the code seems to mutate the state data and adding childs has still to be done properly. I will refactor the code using non mutating functions, as this is related to #27

michaelkrone avatar Dec 05 '17 11:12 michaelkrone

Do you have a rough idea of when you'll get a chance to look at this issue, and the related #27?

Thanks in advance

mecsco avatar Dec 20 '17 10:12 mecsco

Hi,

Do we know when the feature will be pushed to master?

Thank you

pierresigwalt avatar Apr 24 '18 09:04 pierresigwalt