3
votes

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)))
 ); 
2
Hi, so you want to get your state (correctly done with store.select, which returns an object) and then what? You want to stringify the state to populate another property inside your store? You want to change it and update the store with a new value? Couldn't really understand.João Ghignatti
you need to dispatch another action like UpStateSuccess and update the state in your reducer for that action, effects MUST NOT update the storeReza
I uploaded a json file that was the state like so JSON.stringify(state) and now I use FileReader to read that JSON which is a string and want it put back into the state. I am totally new to this and Redux.cdub
this is a little old, concretepage.com/angular-2/ngrx/ngrx-effects-4-example, btw take a look at Effecst with mergemap, to get the conceptsReza
I updated the questioncdub

2 Answers

2
votes

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

0
votes

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.