3
votes

I have the following problem:

Inside a Service I trigger the same ngrx Action in a forEach loop

 sensorCategories.forEach(category => {
     if (category === 'power' || category === 'air-flow') {
       this.store.dispatch(new fromEnergyManagementActions.FetchBigWidgetDataAction({ category: category }));
     } else {
       this.store.dispatch(new fromEnergyManagementActions.FetchSmallWidgetDataAction({ category: category }));
     }
 });

This will then trigger the next side-effect:

@Effect()
fetchSmallWidgetData: Observable<Action> = this.actions
    .ofType(fromEnergyManagementActions.FETCH_SMALL_WIDGET_DATA)
    .map(toPayload)
    .switchMap(payload => this.dashboardDataService.fetchSmallWidgetData(payload))
    .map((data: SmallWidgetData) => new fromEnergyManagementActions.FetchSmallWidgetDataSuccessAction(data))
    .catch(error => of(new fromEnergyManagementActions.FetchSmallWidgetDataFailureAction()));

The method fetchSmallWidgetData from the service will then execute the rest call with the 'new' HttpClient.

Here are the logs: Browser Logs

So the problem is, that the ngrx/effect aborts the previous call. I tested it with a timeout in-between. When the timeout is long enough, everything succeeds.

What is your proposal? Is there a best practice, I could use ? Thanks for your help

1
You might want to consider moving the map and the catch into the switchMap (or mergeMap). As it is, if an error occurs, your effect will stop working, as the stream returned from catch will complete the effect and the framework will be unsubscribed. - cartant

1 Answers

7
votes

This happens because you use switchMap in your effect. Switch to mergeMap to allow multiple inner subscriptions to be maintained.