简体   繁体   中英

Can i use two mergeMap together in RxJs

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 action setCallHistory . 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?

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))),
  ),
  //...

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM