nehalist
nehalist

Reputation: 1496

Adding a delay to an Observable "prevents" subscribing in combination with withLatestFrom

Currently trying to get my head around this:

import {Observable} from "rxjs";
import {delay, first, takeUntil, tap, withLatestFrom} from "rxjs/operators";

const obs1 = new Observable(s => s.next(1)).pipe(delay(1000));
const obs2 = new Observable(s => s.next(2));

obs2
  .pipe(
    withLatestFrom(obs1),
    tap(() => console.log('tap'))
  )
  .subscribe(() => console.log('subscribe'));

"subscribe" (and hence "tap") is never logged. But why?

If I remove the delay from the first Observable everything works. If I change to combineLatest([obs1, obs2]) everything works fine.

This is the reproduction of a bug where 2 HTTP requests are sent. If the request within withLatestFrom took too long the subscribe did never happen. With combineLatest everything works as expected (which means the subscribe happens after both requests are done).

If combineLatest fixes my bug I'm fine with that - but I'd like to understand why.

Upvotes: 2

Views: 1258

Answers (1)

Reactgular
Reactgular

Reputation: 54771

The documentation says:

https://rxjs.dev/api/operators/withLatestFrom

All input Observables must emit at least one value before the output Observable will emit a value.

That is because withLatestFrom() is a non-blocking operator.

obs2 emits the first value, and then withLatestFrom() will emit with the latest value from obs1, but there is no latest value so nothing is emitted.

If obs2 emitted a second value later after obs1 then a value would be emitted.

If combineLatest fixes my bug I'm fine with that - but I'd like to understand why.

combineLatest() works differently, because it emits after all observables emit a value.

Upvotes: 3

Related Questions