Ngrx / saving nested object effects

I am learning Angular 2 and I am trying to use the user's ngrx / store but I have some difficulties with some special cases.

Example. I am trying to remove a parent object. What I want to do is delete the child objects as well.

Here are my entities:

export class Discussion {
  id: string;
  name: string;
  createdAt: Date;
  posts: Post[];
}

export class Post {
  id: string;
  title: string;
  data: string;
  createdAt: Date;
  comments: Comment[];
}

export class Comment {
  id: string;
  data: string;
  createdAt: Date;
}

      

I'm using normalizr to flatten my state, so the saved discussion looks like this:

{
  id: "1",
  name: "First dicussion",
  createdAt: "...",
  posts: ["1", "2", "3", "5"]
}

      

I have 3 reducers, one for discussion, another for posts, and one for comments. All reducers handle deleting an action of their own type. Here's an example of a discussion reducer:

export function reducer(state = initialState, action: discussion.Actions): State {
switch (action.type) {
    case discussion.REMOVE: {
        const idToRemove = action.payload;
        const newEntities = state.entities;
        delete newEntities[idToRemove];
        return Object.assign({}, state, {
            entities: newEntities
        });
    }
}}

      

My actions look like this:

export class RemoveAction implements Action {
readonly type = REMOVE;

/**
 * Constructor
 * @param payload The id of the discussion to remove
 */
constructor(public payload: string) { }
}

      

When I delete a discussion, I want to delete the posts related to the discussion, and the post effect will remove the comments associated with the deleted posts. I used ngrx effects, so I used this effect:

@Effect()
removeDiscussion: Observable<Action> = this._actions
.ofType(dicussion.REMOVE)
.map((action: discussion.RemoveAction) => action.payload)
.mergeMap(discId => {

    // How to get posts from discussion id ???

    // Fire related Actions
    return [
        new posts.RemoveAction(postsToRemove)
    ];
});

      

My question is, how do I get messages to be removed from the discussion Id?

Thanks for reading.

+3


source to share


1 answer


You can access the repository with withLatestFrom

.
( import 'rxjs/add/operator/withLatestFrom';

)

Insert repository into effect class:

constructor(private _actions: Actions, private store: Store<fromRoot.State>)

      



Use it in effect:

@Effect()
removeDiscussion: Observable<Action> = this._actions
    .ofType(dicussion.REMOVE)
    .map((action: discussion.RemoveAction) => action.payload)
    .withLatestFrom(this.store, (payload, state) => ({ discId: payload, state }))
    .mergeMap(({ discId, state }) => {
        // access the posts array of the discussion
        const postsToRemove = state.discussions[discId].posts;

        // Fire related Actions
        return [
            new posts.RemoveAction(postsToRemove)
        ];
    });

      

The syntax .mergeMap(({ discId, state }) => ...

is called destructuring .
If you don't like this syntax, you can replace it with .mergeMap((payloadAndState) => ...

. Then you will access by discId

doingpayloadAndState.discId

+2


source







All Articles