rxjs - Angular 2 update global state as a side effect of updating a certain state -
i want achieve setting global state while requesting data api , storing in state well, in location global state.
i'm calling 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 want 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 can see we're dispatching call 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 mean update global state isloading before , after make http request. however, solution both messy , not work because of simple fact breaks effect (for whatever reason, think it's because call dispatch within effect).
preferably create effect listens set_loading_state calls globalreducer itself, rather letting models$ effect directly.
something (from within global.effects.ts):
@effect() loadingstate$: observable<action> = this.actions$ .oftype(set_loading_state) .do(() => ({type: set_loading_state, payload: thepayloadthatwassent})) but there 2 problems that:
- i don't know how access sent payload in effect.
- i don't know how call effect within
models$effect.
overall i'm confused on how achieve want , there aren't examples of far i've been able find.
if @ image, want update global.isloading when update models:
what best way achieve want?
storing isloading indicator in central place similar done error information. 1 solution storing central error involves using reducer ignores actions' types , looks see if contain error property.
if adopt suitable naming scheme effects' action types, same thing isloading.
one possible naming scheme be:
some_action_request some_action_response some_action_error with such scheme, following reducer examine action types , set isloading state accordingly:
export function isloadingreducer(state: boolean = false, action: action): boolean { if (/_request$/.test(action.type)) { return true; } else if (/(_response|_error)$/.test(action.type)) { return false; } else { return state; } } using boolean value isloading assumes not have concurrent asynchronous effects, if that's issue, extend reducer use counter instead.
if wire things way, isloading indicator doesn't need know individual effects , vice versa.

Comments
Post a Comment