Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait until two Observables are complete

I want to call a method after two Observables have returned values. I did some searching and it seems like forkJoin is what I want, but I can't get it to work. I know both of these Observables are returning values, as I am using the data for each individually elsewhere in the component, so clearly I'm doing something else wrong.

Here is what I tried. I'm using rxjs v6.4.

forkJoin(
  this.store.pipe(select(fromStore.getAppointmentsLoading)),
  this.clientStore.pipe(select(fromClientStore.getClientsLoading)),
).subscribe(
  ([res1, res2]) => {
    console.log('res1', res1);
    console.log('res2', res2);
  },
  err => console.error(err),
);

Nothing is logging to the console and I am not getting any errors. Again, the Observables I am passing in are definitely returning values.

Am I doing something wrong, or am I taking the wrong approach entirely by using forkJoin?

like image 400
Bryan Avatar asked Apr 14 '19 16:04

Bryan


People also ask

How do you wait for two Observables?

While zip method emits the emitted items in sequence order. For example if observable #1 emits its 3rd item and observable #2 has emitted its 5th item. The result using zip method will be the 3rd emitted values of both observables . In this situation the result using combineLatest will be the 5th and 3rd.

What is the difference between combineLatest and forkJoin?

forkJoin - When all observables complete, emit the last emitted value from each. combineLatest - When any observable emits a value, emit the latest value from each.

Is forkJoin deprecated?

forkJoin Improvements Moreover, there is one deprecation — forkJoin(a, b, c, d) should no longer be used; Instead, pass an array such as forkJoin([a, b, c, d]) .

What can I use instead of forkJoin?

concat() which will handle each observable in sequence.


1 Answers

forkJoin emits when all the observables complete (or when one of them throws an error), not when they emit.

You can use combineLatest instead.

Be careful to not import the instance operator from 'rxjs/operators'. It's a common mistake caused by some IDEs auto-import feature. In this case, we need the static version, imported from 'rxjs':

import {combineLatest} from 'rxjs';

combineLatest([
  this.store.pipe(select(fromStore.getAppointmentsLoading)),
  this.clientStore.pipe(select(fromClientStore.getClientsLoading)),
]).subscribe(
  ([res1, res2]) => {
    console.log('res1', res1);
    console.log('res2', res2);
  },
  err => console.error(err),
);
like image 122
julianobrasil Avatar answered Oct 16 '22 15:10

julianobrasil