Search code examples
typescriptrxjsobservable

RxJS: wait for a Subscription to receive the next value


I'm using RxJS in an Angular project and I have a Subscription to an Observable that emits values at a regular interval.

In the same component, I'm also using RxJS (combined with the Angular http client) to make a web call and subscribe to it.

What I want to do is simple: when I make my web call and it has returned a result, I want to wait until the Subscription receives the next value before processing the result. Let's see it better with a code sample:

Suppose I have this Subscription that receives new values from an Observable at regular intervals:

tenantStatusSub: Subscription;

Here's what I want to do, explained in the comment:

this.httpClient.get<any>(...).subscribe({
  next: result => {
      /* I want to wait here for tenantStatusSub to receive a value before proceeding */
  },
  error: err => {
    //...
  }
});

I'm sure there is a straightforward way to do this, but I'm still learning RxJS so I'm not sure what the best/cleanest way is.


Solution

  • I don't think you can wait for the tenantStatusSub-subscription itself. Yet you can wait for the next emission of the observable that the tenantStatusSub-subscription refers to. I suggest you to use switchMap() to chain your http-request directly to the observable that receives the continuous flow of emissions. What's more you can use first(), to trigger "unsubscribe" after the first value has arrived:

    tenantStatusObs$: Observable<any> = observableThatReceivesAFlowOfValues;
    
    ngOnInit(): void {
        this.httpClient.get<any>('http://www.some-url.com').pipe(
            switchMap(resultFromApi => {
                return this.tenantStatusObs$.pipe(
                    first(), // unsubscribes after the first value has been emitted
                    tap(tenantStatus => {
                        console.log('Tenant Status:', tenantStatus);
                        console.log('Result from API:', resultFromApi);
                    })
                )
            })
        )
        .subscribe();
    }