Merge results of array of Observables
It's not entirely clear what behavior you want, but you most likely want either forkJoin, zip, or combineLatest.
forkJoin
When all observables complete, emit an array containing the last emitted value from each.
zip
Subscribe to all inner observables, waiting for each to emit a value. Once this occurs, all values with the corresponding index will be emitted. This will continue until at least one inner observable completes.
combineLatest
When any observable emits a value, emit the latest value from each.
Example:
getTransactionsByIDs(transactionsIDs) {
const transactions = transactionIDs.map(transactionID => this.getTransactionByID(transactionID));
return Observable.forkJoin(...transactions); // change to zip or combineLatest if needed
}
this.transactionsService.getTransactionsByIDs(['1', '2', '3'])
.subscribe(([first, second, third]) => {
console.log({ first, second, third });
});
I think that what you want is combineLatest
. It wont emit any value till all inner observables emit at least one value. After that it will emit the latest from all each time there is a new emit from one of the inner observables.
Here is some reading material: https://www.learnrxjs.io/operators/combination/combinelatest.html
Here is an example:
function getTransactionByID(transactionId) {
let count = 0;
return Rx.Observable.of(transactionId)
.delay(Math.random() * 4000)
.map(x => `${x}: ${count++} `)
.repeat();
}
function getTransactionsByIDs(transactionsIDs){
return Rx.Observable.combineLatest(transactionsIDs.map(transactionID => getTransactionByID(transactionID)));
}
const transactionsIDs = [1,2,3];
getTransactionsByIDs(transactionsIDs)
.take(10)
.subscribe(x => { console.log(x); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>
The take(10)
is just the keep the example from going on forever.