Gini
Gini

Reputation: 85

Timeout Operator of RXJS not working as expected

I have to do polling until I get the response as completed. But I also want to do polling only for 2mins and prevent infinite polling for this I am using timeout operator but that doesn't seem to work.

     interval(5000)
     .pipe(

    startWith(0),
    switchMap(() => this.someService.getQueueJob(jobId)),
    takeUntil(this.stopPolling),
    timeout(2*60000)
  )
  .subscribe((res) => {
    this.jobStatus = res.attributes.status;
    if (this.jobStatus === 'Completed') {
      this.fileUploadStatus = 'success';
      this.stopPolling.next();
    } else if (this.jobStatus === 'Failed') {
      this.fileUploadStatus = 'error';
      this.stopPolling.next();
    }
  });

Also I need to throw error when timeout happens and inform the user.

Upvotes: 1

Views: 740

Answers (2)

Chris
Chris

Reputation: 2427

You can use timer at startup for timeout:

// set time for timeout
timer(2 * 60000).pipe(
  // trow error when timer emit event after 2 minutes
  map(() => { throw new TimeoutError() }),
  // put startWith operator to start before timer emit timeout event
  startWith(0),
  // switch to polling timer for every 5 second
  switchMap(() => timer(0, 5000)),
  // get date from http
  switchMap(() => this.someService.getQueueJob(jobId)),
  // stop manually the polling
  takeUntil(this.stopPolling),
).subscribe(
  (data) => console.log(data),
  (error) => {
    if (error instanceof TimeoutError)
      console.log('time out')
    else
      console.log('http error')
  }
);

Upvotes: 2

Barremian
Barremian

Reputation: 31125

The timeout will be reset everytime there is an emission. So for each emission of the interval and the corresponding this.someService.getQueueJob() its reset. You could accomplish your requirement with an additional takeUntil with the timer function.

Also

  1. You say 2 mins timeout in the question, but the code only has a min.?
  2. As mentioned by @Chris in the comments, you could replace the interval(5000) + startWith(0) combo with timer(0, 5000).
timer(0, 5000).pipe(
  switchMap(() => this.someService.getQueueJob(jobId)),
  takeUntil(this.stopPolling),
  takeUntil(timer(120000))
).subscribe(
  ...
);

Edit 1: Replace interval(5000) + startWith(0) with timer(0, 5000)

Upvotes: 2

Related Questions