1

I'm having trouble dispatching multiple actions in the following effect:

    @Effect()
    someEffect$ = this.actions$.pipe(
      ofType(someAction: Actions),
      mergeMap(
        (action)=>{
          return this.authService.getProfile(action.payload.authInfo).pipe(
              map((response: any) => {

                  if (response.isErrorResponse) {
                    return new HeaderActions.AuthFail(response);
                  } else {

                 //here i'd like to return multiple actions
                    return [
                      new HeaderActions.FetchMPInfoSuccess(this.fetchMpInfoSuccesState(getMpProfileResponse)),
                      new HeaderActions.GetAccountStates(true)
                  ]
                  }
              }),
              catchError((error:HttpErrorResponse )=>{
                return of(new HeaderActions.AuthFail(response));
              })
            );
        }
      )
    );

I've tried adding an array of actions, in the return block, but that's giving an error that im not sending a valid action, any idea what i'm doing wrong?

4
  • 1
    that's not working ← See "It's not working" is not helpful, specifically point 3 and 4. Commented Oct 21, 2019 at 20:39
  • 1. if (response.isErrorResponse) ← that should not have to be checked here, make sure you are building restful APIs that return error status codes on failure. 2. The additional actions you want to execute should not be started in map, use switchMap instead and you can execute the actions simultaneously using forkJoin Commented Oct 21, 2019 at 20:49
  • can you provide that as an answer so I can give it a try? Commented Oct 21, 2019 at 21:04
  • You can take the parts of my comment and search on them and try to alter your code accordingly. Commented Oct 21, 2019 at 21:05

2 Answers 2

4

You can use switchMap instead of mergeMap. Then use flatMap or switchMap instead of map.

The code should be like this:

@Effect()
someEffect$ = this.actions$.pipe(
  ofType(someAction: Actions),
  switchMap(
    (action)=>{
      return this.authService.getProfile(action.payload.authInfo).pipe(
          flatMap((response: any) => {

              if (response.isErrorResponse) {
                return new HeaderActions.AuthFail(response);
              } else {

             //here i'd like to return multiple actions
                return [
                  new HeaderActions.FetchMPInfoSuccess(this.fetchMpInfoSuccesState(getMpProfileResponse)),
                  new HeaderActions.GetAccountStates(true)
              ]
              }
          }),
          catchError((error:HttpErrorResponse )=>{
            return of(new HeaderActions.AuthFail(response));
          })
        );
    }
  )
);

To access data in your child component you can use this approach with @Input() set stuff:

@Input() set(data: any) {
if (data) { console.log(data) }}

The data in html will be there always.

Map modifies each item emitted by a source Observable and emits the modified item.

FlatMap, SwitchMap also applies a function on each emitted item but instead of returning the modified item, it returns the Observable itself which can emit data again.

FlatMap merge items emitted by multiple Observables and returns a single Observable.

SwitchMap is a bit different from FlatMap. SwitchMap unsubscribes from the previous source Observable whenever new item started emitting, thus always emitting the items from current Observable.

If you would like to know more about rxjs operators, please have a look here.

Sign up to request clarification or add additional context in comments.

Comments

-1

Try:


@Effect()
    someEffect$ = this.actions$.pipe(
      ofType(someAction: Actions),
      switchMap(
        (action)=>{
          return this.authService.getProfile(action.payload.authInfo).pipe(
              map((response: any) => {

                  if (response.isErrorResponse) {
                    return [new HeaderActions.AuthFail(response)];
                  } else {

                 //here i'd like to return multiple actions
                    return [
                      new HeaderActions.FetchMPInfoSuccess(this.fetchMpInfoSuccesState(getMpProfileResponse)),
                      new HeaderActions.GetAccountStates(true)
                  ]
                  }
              }),
              catchError((error:HttpErrorResponse )=>{
                return of(new HeaderActions.AuthFail(response));
              })
            );
        }
      )
    );

So basically What I did was, instead of using a mergeMap before the service call, I swapped it back to simple switchMap.

Reason why I changed it from mergeMap was: you are only returning value from a single stream.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.