RXJS Wait for all observables in an array to complete (or error)

You can make usage of zip.

Combines multiple Observables to create an Observable whose values are calculated from the values, in order, of each of its input Observables.

const obsvA = this._service.getObjA();
const obsvB = this._service.getObjB();
// or with array
// const obsvArray = [obsvA, obsvB];

const zip = Observable.zip(obsvA, obsvB);
// or with array
// const zip = Observable.zip(...obsvArray);
zip.subscribe(
  result => console.log(result), // result is an array with the responses [respA, respB]
);

Things to consider:

  • Doesn't need to be an even number of observables.
  • zip visually
  • enter image description here As said here,

    The zip operator will 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.

  • When one of the observables throws an error (or even both of them), the subscription is closed (onComplete on complete is called), and with a onError method, you only get the first error.
  • zip.subscribe(
      result => console.log(result), // result is an array with the responses [respA, respB]
      error => console.log(error), // will return the error message of the first observable that throws error and then finish it
      () => console.log ('completed after first error or if first observable finishes)
    );
    

    If you want to compose an observable that emits when all of the source observables complete, you can use forkJoin:

    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/observable/forkJoin';
    import 'rxjs/add/operator/first';
    
    var tasks$ = [];
    tasks$.push(Observable.timer(1000).first());
    tasks$.push(Observable.timer(3000).first());
    tasks$.push(Observable.timer(10000).first());
    Observable.forkJoin(...tasks$).subscribe(results => { console.log(results); });