michaelkrone / ngrx-normalizr

Managing normalized state in ngrx applications - transparently
https://michaelkrone.github.io/ngrx-normalizr/
MIT License
50 stars 17 forks source link

Add reference to normalized parent when updating normalized child #20

Closed visurel closed 6 years ago

visurel commented 6 years ago

Hey, thanks for this library, really convenient way to handle normalization with ngrx. I've got a question or suggestion:

Say you have the following data:

export class Task {
  id: number;
  name: string;
  comments: Comment[];
}

export class Comment{
  id: number;
  text: string;
}

export const commentSchema = new schema.Entity('comments');
export const taskSchema = new schema.Entity('tasks', { comments: [commentSchema] });

When I now initially load the Tasks and use the AddData action, the data gets normalized into something like this (example):

tasks: [
  "1": {
    id: "1",
    name: 'Example Task',
    comments: ["4"]
  }
],
comments: [
  "4": {
    id: "4",
    text: "My Comment",
    taskId: "1"
  }
]

This is all fine.

But when I now add a new Comment and receive the response from the server, for example:

{
  id: "8",
  text: "Second Comment",
  taskId: "1"
}

and then use AddData again, it'll probably only get added to the normalized comments array and not added to tasks["1"].comments.

How it should look in the end:

tasks: [
  "1": {
    id: "1",
    name: 'Example Task',
    comments: ["4", // "8" <-- How to add this]
  }
],
comments: [
  "4": {
    id: "4",
    text: "My Comment",
    taskId: "1"
  },
  "8": {
    id: "8",
    text: "Second Comment",
    taskId: "1"
  },
]

Is there any way to achieve this? Or how is one supposed to achieve this behaviour? Sure, it's possible to query the tasks again, with the updated relations, but wouldn't this be a bit overkill? I think there should be a way to achieve this and I think it would be great if this would be possible with this lib (or maybe it already is?).

Hope you can point me in the right direction! :+1:

michaelkrone commented 6 years ago

Hello @visurel You are describing a common use case and ngrx-normalizr should definitely help with this problem - unfortunately, with version 2.0.0 and above, your described use case broke.

I think about how to keep the actions serializable and take advantage of normalizr's schema bound merge- and processStrategy. This would easily enable advanced merge strategies. Stay tuned.

michaelkrone commented 6 years ago

I am preparing a new release which will have AddChildData and RemoveChildData actions, you might play with them in the current develop branch, will be released with version 2.2.0

tommueller commented 6 years ago

thanks @michaelkrone, I will check out the current dev-version and try to give you some feedback!

tommueller commented 6 years ago

@michaelkrone okay I just tested this and have some problems. My call dispatching looks like this:

this.store.dispatch(new AddChildData<Section>({ childSchema: sectionSchema, parentId: page.id, data: [ section ], schema: pageSchema }));

I assume schema is the parent-schema? maybe that could be renamed so that it is more clear.

This now adds the section to the correct parent, but the reference in the parent is not added correctly, but as a nested element, see the screenshot from the Redux-DevTools auswahl_003

michaelkrone commented 6 years ago

@tommueller Thank you for your feedback, will look into this

michaelkrone commented 6 years ago

Hello @tommueller I fixed the described bug and changed the parameter name to parentSchema, for a better distinction with the childSchema as you suggested. Maybe you will look into it. If there are no more bugs this will be released as a 2.2.0 feature release.

tommueller commented 6 years ago

@michaelkrone working for me, thanks!

michaelkrone commented 6 years ago

@tommueller OK, will publish a release later this day, thank you for your feedback