Single action dispatch results in multiple effect call until Maximum call stack size exceded

766 Views Asked by At
@effect()
public loadAccommodations$: Observable = this.actions$
  .ofType(PAA.PROPERTY_LOAD_REQUEST)
      // .debounce(300) 
      // introducing this mitigates the flood but does not resolve the issue
  .switchMap((action: Action) => {
     return this.propertyAccommodationsService.loadAccommodations(action.payload.id)
      .takeUntil(this.loadAccommodations$)
      .map((response: IResponseSuccess) => PAA.loadSuccess(action.payload, response))
      .catch((error: Error) => {
         const errorNotification = errorNotificationFactory(error.message);
         this.notificationService(errorNotification)
         return of( PAA.loadFailure() );
    });
  });

After dispatch PAA.PROPERTY_LOAD_REQUEST only once my effect intercepts this action many times until Maximum call stack size exceeded.

Versions: "angular/core": "2.4.6",

"@ngrx/core": "^1.2.0",

"@ngrx/store": "^2.2.1",

"@ngrx/effects": "^2.0.1",

"rxjs": "5.0.2",

Note: effects are registered only once in app.module.

2

There are 2 best solutions below

4
On

An @Effect does dispatch an Action itself. Your Effect dispatches the same Action again and again until either the call-stack is exeeded or the call returns.

You need to add dispatch: false to the Effect decorator:

@Effect({ dispatch: false })

Or you dispatch another action:

.switchMap((action: Action) => {
    this.propertyService.load(action.payload);
    return Observable.of({ type: 'LOADING_DATA' });
});
0
On

In my case the problem was caused by takeUntil in this piece of code:

 return this.propertyAccommodationsService
   .loadAccommodations(action.payload.id)
   .takeUntil(this.loadAccommodations$) 

By dispatching 2 PROPERTY_LOAD_REQUEST actions, the second one triggered takeUntil() operator which resulted in multiple effects calls. In my case takeUntil(effect) is unnecessary so I could delete it but still, I can't figure out why this operator results in running multiple times the effect.