I want to achieve setting a global state while also requesting data from an api and storing that in the state as well, but in another location than the global state.
I'm calling this effect (models.effects.ts
):
@Effect() models$: Observable<Action> = this.actions$
.ofType(GET_MODELS)
.switchMap(() => this.modelsApi.getModels())
.map(models => ({type: SET_MODELS, payload: models}))
.catch((err: any) => Observable.of({type: GET_FAILURE, payload: {error: err}}))
Now what I want to do is something like this:
@Effect() models$: Observable<Action> = this.actions$
.ofType(GET_MODELS)
.do(() => this.store.dispatch({type: 'SET_LOADING_STATE', payload: true}))
.switchMap(() => this.modelsApi.getModels())
.map(models => ({type: SET_MODELS, payload: models}))
.do(() => this.store.dispatch({type: 'SET_LOADING_STATE', payload: false}))
.catch((err: any) => Observable.of({type: GET_FAILURE, payload: {error: err}}))
As you can see we're dispatching a call to the globalReducer
(global.reducer.ts
):
export const GlobalReducer: ActionReducer<any> = (state: IGlobalStorage = {isLoading: false}, action: Action) => {
switch(action.type) {
case SET_LOADING_STATE: return Object.assign({}, state, {
isLoading: action.payload
});
default: return state;
}
}
Which would mean that I update the global state isLoading
before and after we make an http request. However, this solution is both messy and does not work because of the simple fact that it breaks the effect (for whatever reason, I think it's because I call dispatch within the effect).
Preferably I would like to create another effect which listens to SET_LOADING_STATE
which then calls the globalReducer
itself, rather than letting the models$
effect do it directly.
Something like this (from within global.effects.ts
):
@Effect() loadingState$: Observable<Action> = this.actions$
.ofType(SET_LOADING_STATE)
.do(() => ({type: SET_LOADING_STATE, payload: thePayloadThatWasSent}))
But there are 2 problems with that:
- I don't know how to access a sent payload in an effect.
- I don't know how to call that effect from within the
models$
effect.
Overall I'm just really confused on how to achieve what I want and there aren't any examples of this as far as I've been able to find.
If you look at this image, I want to update global.isLoading
when I update models
:
What would be the best way to achieve what I want?
See Question&Answers more detail:
os