0

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]}) ) 
        );
    }
Thierry Falvo
  • 5,892
  • 2
  • 21
  • 39
Vardges
  • 3
  • 1
  • `switchMap` expects an Observable, Promise, Array, or Iterable but you provide an `Action`. – frido Mar 27 '20 at 11:21

1 Answers1

0

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 :

Thierry Falvo
  • 5,892
  • 2
  • 21
  • 39
  • does it mean I could also just put the action into an array like this ? @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]})] ) ); } – Vardges Mar 27 '20 at 13:01
  • it means `switchMap(() => [x])` will have similar effect than `map(() => x)`, by emitting the unique value in array. but syntax of `map` is more clear in this case. – Thierry Falvo Mar 27 '20 at 13:04
  • It's a pleasure, you're welcome on SO. However please take time to read https://stackoverflow.com/help/someone-answers. Upvote is better than adding comment. Thanks. – Thierry Falvo Mar 27 '20 at 13:16