cdub
cdub

Reputation: 25701

Repopulating state in an NgRx Effect

I have JSON that is in my effect that was initially a JSON.stringify(state) and need to add that JSON string back into the state to update the app. (New to Angular and NgRx/Redux).

I have an effect like so (which I'm probably doing wrong):

@Effect({ dispatch: false })
upState$ = this.actions$.pipe(
   ofType(WorkspaceActionTypes.UpState),
   withLatestFrom(this.store.select(fromSpace.getState)),
   tap(([empty, space]) => {
        console.log(JSON.stringify(space));

       var json = "my json file in string form";
       space = json;
   })

);

The json can't go from a string to a type State.

UPDATE:

After looking at the link in the comments, am I supposed to create an effect that calls an action that calls a reducer to update the state? I see this from the link but not sure how to use it yet:

@Effect() 
createArticle$: Observable<Action> = this.actions$
 .ofType<fromActions.CreateAction>(fromActions.CREATE)
 .map(action => action.payload)
 .mergeMap(article => 
     this.articleService.createArticle(article)
     .map(res => new fromActions.CreateSuccessAction(res)) 
     .catch(error => of(new fromActions.CreateFailureAction(error)))
 ); 

Upvotes: 3

Views: 1583

Answers (2)

thomi
thomi

Reputation: 1687

Could you add the code for your reducer? You should deserialize your JSON string in the effect. Then, the effect should dispatch an action which is caught by your reducer. Your reducer then updates the state (it is the only function allowed to do so in redux/ngrx). It typically would look something like:

switch(action.type){

//... other cases
case CreateSuccessAction: 
  return {...state, article: action.payload} // <-- or whatever the shape of your state looks like.
// more other cases...

}

Note: I don't know which version of ngrx you are using, and whether you are using enums for your state types or const strings. But basically, you filter for the action type in a switch and case (newest version has creator functions which reduce boilerplate).

Ngrx/Redux basically works like this: Actions are triggered by the app, and caught by a reducer. The reducer is a pure function which updates the store immutably. Because a reducer should not have side effects, the effects module takes care of things like logging, db stuff, file i/o... or JSON serialization/deserialization. So put your JSON into an action payload, dispatch that, and let the reducer do the state update.

Also, as a side note. If you do not need the observables from your effect hanging around, I think it's safer to use switchMap instead of mergeMap. That way, the effect cancels all subscriptions in favor of the new observable. Keeps away possible memory leaks

Upvotes: 2

Albondi
Albondi

Reputation: 1151

Create a handler in your reducer that gets an object ( the parsed JSON), then you can assing your state attributes manually. JSON.parse won't create a new instance of State, you have to do use your current state and set the attributes on the reducer like this.

Upvotes: 0

Related Questions