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:

  1. i don't know how access sent payload in effect.
  2. 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:

redux dev tools

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

Popular posts from this blog

php - How to add and update images or image url in Volusion using Volusion API -

javascript - jQuery UI Splitter/Resizable for unlimited amount of columns -

javascript - IE9 error '$'is not defined -