How to 'wait' for two observables in RxJS

Viewed 114015

In my app i have something like:

this._personService.getName(id)
      .concat(this._documentService.getDocument())
      .subscribe((response) => {
                  console.log(response)
                  this.showForm()
       });

 //Output: 
 // [getnameResult]
 // [getDocumentResult]

 // I want:
 // [getnameResult][getDocumentResult]

Then i get two separated results, first of the _personService and then the _documentService. How can I wait for both results before call this.showForm() to finish an then manipulate the results of each one.

8 Answers

Improvement of Hamid Asghari answer which use direct arguments decomposition and automatically add types (when you use typescript)

const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();

combineLatest([name$, document$]).subscribe(([name, document]) => {
    this.name = name;
    this.document = document;
    this.showForm();
});

BONUS: You can also handle errors using above approach as follows

import { combineLatest, of } from 'rxjs';
//...

const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();

combineLatest([
  name$.pipe(     catchError( () => of(null as string  ) ) ), 
  document$.pipe( catchError( () => of(null as Document) ) ), // 'Document' is arbitrary type
]).subscribe(([name, document]) => {
    this.name = name;          // or null if error
    this.document = document;  // or null if error
    this.showForm();
});

June 2021

With rxjs 6.6.7

Use combineLatest like this otherwise is deprecated

combineLatest([a$ , b$]).pipe(
      map(([a, b]) => ({a, b})) //change to [a , b] if you want an array
    )

Also see @nyxz post

zip - the love birds, always work as a team, triggers only when all observables return new values

combineLatest - the go dutch, start trigger once all observables return new values, then wait for no man, trigger every time when either observable return new value.

withLatestFrom - the master slave, master first waits for slave, after that, action get triggered every time only when master return new value.

forkJoin - the final destination, trigger once when all observables have completed.

From : https://scotch.io/tutorials/rxjs-operators-for-dummies-forkjoin-zip-combinelatest-withlatestfrom/amp

Related