Home > Back-end >  RxJS: wait for a Subscription to receive the next value
RxJS: wait for a Subscription to receive the next value

Time:12-20

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.

CodePudding user response:

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();
}

CodePudding user response:

CombineLatest should do this out of the box, since httpClient will emit just once and complete, all the edge cases are taken care of for you.

combineLatest([
  tenantStatusSub,
  this.httpClient.get<any>(...)
]).subscribe({
  next: result => {
    // both values in result here
  },
  error: err => {
    //...
  }
});
  • Related