Multiple nested observable with SwitchMap

361 Views Asked by At

In my scenario, I have an higher order observable which when emits we needs to fetch two different pieces of data as inner observables.

something like

    $someDetails.pipe(
switchMap(sd => {
this.name = sd.name;
let innerObservableOne = getObservableOne(this.name);
let innerObservableTwo = getObservableTwo(this.name);
return {one: innerObservableOne, two: innerObservableTwo}
}).subscribe(r => ?????)

Can I get some lead on this?

Do I need to do something like this

https://medium.com/@snorredanielsen/rxjs-accessing-a-previous-value-further-down-the-pipe-chain-b881026701c1

The other option I have is to use two switchmaps one for each inner observable but that means two subscriptions which seems unnecessary.

$someDetails.pipe(
    switchMap(sd => {
    return getObservableOne(sd.name);
}).subscribe(.....);


$someDetails.pipe(
    switchMap(sd => {
    return getObservableTwo(sd.name);
}).subscribe(.....);

Edit1:

Any issues with following code:-

What about the following code.

details$ = $someDetails.pipe(share());

details$.pipe(switchMap(sd => getObservableOne(sd.name)).subscribe(...);
details$.pipe(switchMap(sd => getObservableTwo(sd.name)).subscribe(...);

Any thoughts or issues you see with this solution ?

1

There are 1 best solutions below

4
ccjmne On

You want forkJoin:

import { forkJoin, interval, map, switchMap, timer } from 'rxjs'

interval(1000).pipe(
  switchMap(x => forkJoin([
    timer(100).pipe(map(() => `apple #${x}`)),
    timer(200).pipe(map(() => `orange #${x}`)),
  ])),
).subscribe(([apple, orange]) => console.log([apple, orange]))

This is the equivalent of Promise.all and will wait until multiple concurrent Observables have completed, then it will emit once, aggregating the last values emitted by each "inner query".

In the example above, every second (with interval(1000)), I spawn two new queries, fetching an apple and an orange, respectively. The query that retrieves an apple completes in 100ms, the one for the orange takes 200ms (with timer).

For completeness' sake, here's the output of the above example:

[ 'apple #0', 'orange #0' ]
[ 'apple #1', 'orange #1' ]
[ 'apple #2', 'orange #2' ]
[ 'apple #3', 'orange #3' ]
[ 'apple #4', 'orange #4' ]
...