Search code examples
angularrxjsngrx

NgRx effects combined with RxJS operators


Does anyone know why the switchMap operator is not working ?

I have tried to put second map operator instead and it worked but I am not getting why switchMap is not working.

    @Injectable()
    export class PizzasEffects {
        constructor(private actions: Actions, private pizzasService: PizzasService) {}

    @Effect()
        createPizzaSuccess$ = this.actions.ofType( fromPizzasActions.CREATE_PIZZA_SUCCESS ).pipe(
          map( (action: fromPizzasActions.CreatePizzaSuccess) => action.payload ),
          switchMap( (pizza: Pizza) => new  fromRouterActions.Go({path: ['products', pizza.id]}) ) 
        );
    }

Solution

  • Use simply map operator in place of switchMap as below :

    @Effect()
      createPizzaSuccess$ = this.actions.ofType(fromPizzasActions.CREATE_PIZZA_SUCCESS).pipe(
          map(action => action.payload),
          map(pizza => new fromRouterActions.Go({path: ['products', pizza.id]})) 
    );
    

    switchMap operator is expecting an Observable. For example, to return the result of a HttpClient.get :

    @Effect()
      createPizzaSuccess$ = this.actions.ofType(fromPizzasActions.CREATE_PIZZA_SUCCESS).pipe(
      map(action => action.payload),
      switchMap(pizza => this.httpClient.get(URL)) 
    );
    

    But in your case, value emitted is only an Action, so map operator is the correct choice, exactly like you did to extract payload from action.

    Note also that switchMap is expecting a stream, and you can provide an Observable, Promise, Array, or Iterable.

    It means, in the case of NgRx, it could be useful in certain situation, to return multiple actions for one effect, so an array of actions :

    @Effect()
      createPizzaSuccess$ = this.actions.ofType(fromPizzasActions.CREATE_PIZZA_SUCCESS).pipe(
      map(action => action.payload),
      switchMap(pizza => [
        new fromUIActions.showNotification({ message: 'Pizza loaded' }),
        new fromRouterActions.Go({path: ['products', pizza.id]})
      ]) 
    );
    

    More explanation :