Home > Net >  Ngrx Effects - how to dispatch two actions?
Ngrx Effects - how to dispatch two actions?

Time:10-12

Is there a way to dispatch multiple actions in a createEffect function?

    loadMovies$ = createEffect(() =>
      this.actions$.pipe(
        ofType('[Movies Page] Load Movies'),
        mergeMap(() =>
          this.moviesService.getAll().pipe(
            map(movies => /* return an array of actions */ [
              { type: '[Movies API] Movies Loaded Success', payload: movies },
              { type: '[Movies API] Movies Loaded Success 2', payload: movies },
            ])
          )
        )
      )
    );

When I launch the service I need to dispatch to actions, but it gives me an error and I can't find a real solution. Why?

CodePudding user response:

Try switchMap

  loadMovies$ = createEffect(() =>
          this.actions$.pipe(
            ofType('[Movies Page] Load Movies'),
            mergeMap(() =>
              this.moviesService.getAll().pipe(
                switchMap(movies => /* return an array of actions */ [
                  { type: '[Movies API] Movies Loaded Success', payload: movies },
                  { type: '[Movies API] Movies Loaded Success 2', payload: movies },
                ])
              )
            )
          )
        );

CodePudding user response:

I would recommend using a switchMap in this case to return an Observable array of actions.

this.actions.pipe(
 ofType(Actions.YourType),
  switchMap(() => {
    return this.moviesService
               .getAll()
               .pipe(
                 switchMap(movies => {
                   return [
                     Actions.action1({ movies }),
                     Actions.action2({ movies }),
                   ];
                 }),
               );
  }),
)

It's not considered best practice to return more than one action from an effect, but sometimes it's unavoidable based on your application's needs.

CodePudding user response:

The return should be an observable array instead of an array.

If order is important, you can use concatmap and if not, then mergemap

loadMovies$ = createEffect(() =>
      this.actions$.pipe(
        ofType('[Movies Page] Load Movies'),
        mergeMap(() =>
          this.moviesService.getAll().pipe(
            map(movies => /* return an array of actions */ concatMap([
              { type: '[Movies API] Movies Loaded Success', payload: movies },
              { type: '[Movies API] Movies Loaded Success 2', payload: movies },
            ])) 
          )
        )
      )
    );

CodePudding user response:

Try to use tap instaded of map

import { tap } from 'rxjs/operators';

So you do not need to return something, you can use tap to set side effects, in your case dispatch two actions

  • Related