Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RXJS: Conditional map or mergeMap

Tags:

rxjs

If I have a method that sometimes returns a string and sometimes returns a promise that results in a string how can I chain that in my observable?

Example

function doSomething() {
    if (Math.random() < 0.5) {
        return 'test';
    }

    return new Promise(resolve => resolve('test'));
}

const example = of(undefined).pipe(
    mergeMap(() => doSomething())
);

const subscribe = example.subscribe(val => console.log(val));

I would like to always log "test".

like image 922
joshhunt Avatar asked Aug 09 '18 00:08

joshhunt


People also ask

What is the difference between map and mergeMap?

mergeMap is a combination of Observable merge and map . There are times when your map or projection will generate multiple Observables. For example, now I have an array of characters, and for each character, I would like to make a backend call and get some information.

When should we use the switchMap mergeMap and concatMap in RxJS?

Use mergeMap if you simply want to flatten the data into one Observable, use switchMap if you need to flatten the data into one Observable but only need the latest value and use concatMap if you need to flatten the data into one Observable and the order is important to you.

What is difference between switchMap and mergeMap?

So here's the simple difference — switchMap cancels previous HTTP requests that are still in progress, while mergeMap lets all of them finish. In my case, I needed all requests to go through, as this is a metrics service that's supposed to log all actions that the user performs on the web page, so I used mergeMap .

What is mergeMap in RxJS?

RxJS mergeMap() operator is a transformation operator that applies a project function on each source value of an Observable, which is later merged in the output Observable.


1 Answers

One way of solving the problem would be to make the function passed to mergeMap an async function and to await the return value of doSomething, like this:

const example = of(undefined).pipe(
  mergeMap(async () => await doSomething())
);

You can do this because mergeMap expects the function to return an ObservableInput and a promise is a valid ObservableInput.

Doing so takes advantage of that fact await will accept either a promise or an ordinary value - to which the promise returned by the async function will resolve.

like image 186
cartant Avatar answered Oct 10 '22 21:10

cartant