Stuck in an infinite loop when not sending an action to ngrx / effects

I use Angular2 and ngrx / store and ngrx / effects to manage state.

When some action fails, I want to show an error message, but it seems that I cannot complete this task in the @Effects() block. See the following:

  @Effect() selectOfficeFail$ = this.actions$ .ofType(SelectOfficeActions.LOAD_FAIL) .do(() => { alert('Error! No offices found!'); // I keep entering here }); 

When the above code triggers a warning, it runs infinitely many times until the browser crashes. It seems that @Effect() should return a new dispatch() , but I don't understand why. And why does the warning () above trigger an infinite number of times?

Edit: I do not send SelectOfficeActions.LOAD_FAIL several times. Just one time

+6
source share
3 answers

The problem is that do allows the action to flow through your effect, and the action is then sent again by the store. You can use filter to prevent this from happening:

 @Effect() selectOfficeFail$ = this.actions$ .ofType(SelectOfficeActions.LOAD_FAIL) .do(() => { alert('Error! No offices found!'); // I keep entering here }) .filter(() => false); 
+4
source

[UPDATE] Now the best way to do this is to use the dispatch parameter as follows:

 @Effect({dispatch: false}) selectOfficeFail$ = this.actions$ .ofType(SelectOfficeActions.LOAD_FAIL) .do(() => { alert('Error! No offices found!'); // I keep entering here }); 

This means that "responds to this action, but does not send another."

+9
source

Yes, you're right, @effect needs to send a new action, but I think something is wrong with your application logic.

You should not send the SelectOfficeActions.LOAD_FAIL action in the component or service, but rather the LOAD action, which calls @effect , and the effect, in turn, sends LOAD_COMPLETE or LOAD_FAIL based on the criteria.

Something like an example from github libraries

  @Effect() login$ = this.updates$ // Listen for the 'LOGIN' action .whenAction('LOGIN') // Map the payload into JSON to use as the request body .map(update => JSON.stringify(update.action.payload)) .switchMap(payload => this.http.post('/auth', payload) // If successful, dispatch success action with result .map(res => ({ type: 'LOGIN_SUCCESS', payload: res.json() })) // If request fails, dispatch failed action .catch(() => Observable.of({ type: 'LOGIN_FAILED' })); ); 
0
source

All Articles