Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dispatch multiple actions from an effect in ngrx conditionally

I am a back-end developer starting with front-end development for a project I am working on. The front-end uses Angular7 and NgRx. I have studied a lot in the last 4 days, but here is something I am stuck with and would appreciate your help.

I learnt that we can dispatch multiple actions from an effect in NgRx by returning an Observable array having multiple actions. I want to dispatch one of the action in the array based on a condition.

My code looks something like this

@Effect()
  something$: Observable<Action> = this.actions$.pipe(
    ofType(ActionType),
    switchMap.(action: any) => {
       return service.call(action.payload)
         .pipe(
             switchMap((data: ReturnType) => [ 
                new Action1(),
                new Action2(),
              ]),
        catchError(error handling)
      );
    }),
   );

and I want to achieve something like this

   @Effect()
  something$: Observable<Action> = this.actions$.pipe(
    ofType(ActionType),
    switchMap.(action: any) => {
       return service.call(action.payload)
         .pipe(
             switchMap((data: ReturnType) => [ 
                 if(condition)
                   new Action1()
                  else
                    new Action1.1() ,
                new Action2(),
              ]),
        catchError(error handling)
      );
    }),
   );

I think its my lack of knowledge of RxJs, which is preventing me to implement the condition.

like image 594
Akash Sharma Avatar asked Oct 15 '25 12:10

Akash Sharma


2 Answers

You can dispatch multiple actions or specific actions by letting conditional ifs determine what iterable to return

I recommend you read: https://www.learnrxjs.io/operators/transformation/switchmap.html

  @Effect()
  something$: Observable<Action> = this.actions$.pipe(
    ofType(ActionType),
    switchMap(action: any) => {
       return service.call(action.payload)
         .pipe(
             switchMap((data: ReturnType) => {
                 let actionsToDispatch = [];
                 if(condition) {
                   actionsToDispatch.push(new SomeAction())
                 } else {
                   actionsToDispatch.push(new SomeOtherAction())
                 }
                 return actionsToDispatch
              }),
              catchError(error handling)
      );
    }),
   );

like image 154
Alex Fallenstedt Avatar answered Oct 17 '25 21:10

Alex Fallenstedt


To dispatch multiple actions you can pass the action array as shown below:

@Effect()
getTodos$ = this.actions$.ofType(todoActions.LOAD_TODOS).pipe(
  switchMap(() => {
    return this.todoService
      .getTodos()
      .pipe(
        switchMap(todos => [
          new todoActions.LoadTodosSuccess(todos),
          new todoActions.ShowAnimation()
        ]),
        catchError(error => of(new todoActions.LoadTodosFail(error)))
      );
  })
);

To dispatch actions conditionally you can wrap the actions in if/else as shown below:

@Effect()
getTodos$ = this.actions$.ofType(todoActions.LOAD_TODOS).pipe(
  switchMap(() => {
    return this.todoService
      .getTodos()
      .pipe(
        switchMap(todos => {
         if(true) {
             return new todoActions.LoadTodosSuccess(todos),
         } else {
            return new todoActions.ShowAnimation()
         }),
        catchError(error => of(new todoActions.LoadTodosFail(error)))
      );
  })
);

Hope that helps!

like image 24
Shivam Latawa Avatar answered Oct 17 '25 20:10

Shivam Latawa