1
votes

I have an observable stream. The first operator is a mergeMap that returns an array of observables. I then have to have a second mergeMap to get the final values from the first mergeMap's return. I feel this second mergeMap should be unnecessary, but cannot find a way around it.

Example:

source$.pipe(
  mergeMap(() => [of(1), of(2), of(3)]),
  mergeMap((val) => val)
)

This is ultimately what I have. The second mergeMap only exists to subscribe to the output of the first. Without it, my output is the observable (i.e. of(1) instead of the actual value 1). Is there a way around having this second mergeMap?

2

2 Answers

3
votes

You can use the merge function inside your mergeMap operator to merge all observables inside your array of Observables into one single observable that will emit when any underlying observable emits.

The snippet for this would be:

source$.pipe(
  mergeMap(() => merge(...[of(1), of(2), of(3)])),
)
0
votes

The reason is that the first mergeMap is applied to the array, whatever array.

In other words

source$.pipe(
  mergeMap(() => ['a', 'b', 'c']),
)

emits firtst a then b then c and then completes.

So, in your case you need the second mergeMap to flatten the Observables emitted.

As an alternative approach, if it makes sense in your case, you could use forkJoin rather than mergeMap. Something like this

source$.pipe(
  forkJoin([of(1), of(2), of(3)]),
)
.subscribe(console.log) // '1' '2' '3'