Combine a fixed number of mergeMapped observables - RxJS

Combine a fixed number of mergeMapped observables - RxJS



I'm using RxJS v6, but this question applies to v5 as well.



When using mergeMap, my original array disappears and while I can do a number of operations in parallel, I no longer have a way of monitoring when all those observables I sent into mergeMap are complete.


mergeMap


mergeMap



Example


of([1, 2, 3, 4])
.pipe(
mergeMap(values => values),
)
.subscribe(console.log)

// 1
// 2
// 3
// 4



I'd like to see:


// [1, 2, 3, 4]



The only way I've come up with so far requires getting the length of the array, but I'm sure there's gotta be some operator I'm missing:


of([1, 2, 3, 4])
.pipe(
switchMap(values => (
of(values)
.pipe(
mergeMap(value => value),
bufferCount(values.length),
)
))
)
.subscribe(console.log)






It sounds like you are looking for the toArray operator. Or, if the order is important, the forkJoin factory function.

– cartant
Sep 8 '18 at 5:15


toArray


forkJoin




1 Answer
1



When using mergeMap, my original array disappears



The reason is that mergeMap accepts an ObservableInput as parameter of the function you pass in. A javascript Array is an ObservableInput and therefore works in mergeMap and mergeMap does its job, which is to flatten the ObservableInput (consider that mergeMap was previously called flatMap).


mergeMap


ObservableInput


Array


ObservableInput


mergeMap


mergeMap


ObservableInput


mergeMap


flatMap



So, as @cartant says, if you want to get back to an array, you have to use toArray operator.
In other words


toArray


of([1, 2, 3, 4])
.pipe(
mergeMap(value => // do stuff with a value of an array),
toArray()
)
.subscribe(console.log)



is equivalent to


of([1, 2, 3, 4])
.pipe(
map(values => values.map(value => // do stuff with a value of an array)),
)



If your array though contains Observables and you want to eventually get the values they notify when all of them emit, than you have to use forkJoin. This is a simple example


forkJoin


of([1, 2, 3, 4].map(n => of(n)))
.pipe(
switchMap(observablesOfValues => forkJoin(observablesOfValues))
)
.subscribe(console.log)






toArray, which I didn't know existed in RxJS v5+, solved it for me! It allowed me to execute a bunch of observables asynchronously and optionally wait for all of them to finish to do something else.

– Sawtaytoes
Sep 14 '18 at 1:57


toArray



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)