Home > Software design >  Can i use two mergeMap together in RxJs
Can i use two mergeMap together in RxJs

Time:10-28

I have been started using RxJs with redux and i have created a stream which is working. Here's my action pipe:

action$.pipe(
            ofType(DELETE_CALL_HISTORY),
            withLatestFrom(state$),
            mergeMap(() =>
                fromPromise(accessService.getCallHistory()).pipe(
                    mergeMap((res: any) => of(deleteCallHistory(res))),
                    mergeMap((res: any) => of(setCallHistory(res.param))),
                    catchError((err: any) => {
                        console.error(err);
                        return of(
                            showErrorAndHideAfterDelay({
                                message: err,
                                label: 'Error',
                            }),
                        );
                    }),

                ),
            ),
        ),

Here i have been trying to use three actions. getCallHistory action is fetching the data first. deleteCallHistory action is deleting an item from the list. The action pipe is working till here. After this, i'm trying to set the updated list with the actionsetCallHistory. But this is not working. The setCallHistory action is getting called but when i reload the app, the deleted items are back. Should i use mergeMap like this twice or do need to use anything else?

CodePudding user response:

Note to your code:

  // ...
  mergeMap((res: any) => of(deleteCallHistory(res))),
  // now pipeline contains response of the deleteCallHistory
  mergeMap((res: any) => of(setCallHistory(res.param))), 
  //...

Don't you forget wrap the API calls with fromPromise?:

  // ...
  mergeMap((res: any) => fromPromise(deleteCallHistory(res))),
  // now pipeline contains response of the deleteCallHistory
  mergeMap((res: any) => fromPromise(setCallHistory(res.param))), 
  //...

To execute N API calls in sequence use concat:

  import { concat } from 'rxjs';
  // ...
  mergeMap((res: any) => concat(
    of(deleteCallHistory(res))),
    of(setCallHistory(res.param))),
  ),
  //...

To execute N API calls in parallel use merge:

  import { merge } from 'rxjs';
  // ...
  mergeMap((res: any) => merge(
    of(deleteCallHistory(res))),
    of(setCallHistory(res.param))),
  ),
  //...

CodePudding user response:

Why are you calling mergeMap and use of on the inside?

The following are very close to being equivalent:

mergeMap((res: any) => of(deleteCallHistory(res)))
map((res: any) => deleteCallHistory(res)))

They will both pass the result of deleteCallHistory on in the stream. The mistake is likely there. If deleteCallHistory returns an observable then that observable will never be executed since the result is an observable wrapped in an observable by of.

So, if deleteCallHistory returns a promise or observable you can just call mergeMap without having to wrap deleteCallHistory in anything:

mergeMap((res: any) => deleteCallHistory(res))

This could be an issue when calling setCallHistory as well. If you don't need to pass along the result from it, you can use tap or do and if it returns an observable or promise, then don't use of.

  • Related