Home > front end >  How to retry with delay in RxJs without using the deprecated retryWhen?
How to retry with delay in RxJs without using the deprecated retryWhen?

Time:06-13

I want to retry an observable chain with a delay (say, 2 sec).

There are some similar questions answered with retryWhen. But retryWhen seem deprecated and I don't want to use it.

  • The delay and retry is applicable only if the first try fails
  • If all the retries failed, I want to respond with a default data.

The following code works, without adding the delay. And I don't know how to add delay into this chain.

of('trigger')
  .pipe(
    switchMap(() => fetchData()),
    retry(5),
    catchError(() => of(returnThisIfRetriesAreFailed))
  )
  .subscribe(console.log);

stackblitz

I tried adding delay(2000), but seem not working.

CodePudding user response:

Not sure what you mean by

The delay and retry is applicable only if the first try fails

I couldn't find any condition in the source code that would limit the delay option to be applicable only to the first failed attempt.

So you should be able to pass as a delay either a fixed number or an Observable. For example:

of('trigger')
  .pipe(
    switchMap(() => fetchData()),
    retry({count: 5, delay: 2000}),
    catchError(() => of(returnThisIfRetriesAreFailed))
  )
  .subscribe(console.log);

If you meant you only want to delay on the first retry, then you could try something like this:

of('trigger')
  .pipe(
    switchMap(() => fetchData()),
    retry({count: 5, delay: (_, retryCount) => retryCount === 1 ? timer(2000) : of({})}),
    catchError(() => of(returnThisIfRetriesAreFailed))
  )
  .subscribe(console.log);

CodePudding user response:

Fix after Tobias's comment:

of('trigger').pipe(
    switchMap(() => fetchData()),
    catchError((err, caught) => caught.pipe(
                    repeat({ count: 1, delay: 2000 }),
                    catchError(() => of(returnThisIfRetriesAreFailed))
              ))
)
.subscribe(console.log);
  • Related