Reputation: 3868
I am trying to make an API call (using angular4), which retries when it fails, using retryWhen. I want it to delay for 500 ms and retry again. This can be achieved with this code:
loadSomething(): Observable<SomeInterface> {
return this.http.get(this.someEndpoint, commonHttpHeaders())
.retryWhen(errors => errors.delay(500));
}
But this will keep trying forever. How do I limit it to, let's say 10 times?
Thank you!
Upvotes: 32
Views: 24030
Reputation: 18663
You need to apply the limit to the retry signal, for instance if you only wanted 10 retries:
loadSomething(): Observable<SomeInterface> {
return this.http.get(this.someEndpoint, commonHttpHeaders())
.retryWhen(errors =>
// Time shift the retry
errors.delay(500)
// Only take 10 items
.take(10)
// Throw an exception to signal that the error needs to be propagated
.concat(Rx.Observable.throw(new Error('Retry limit exceeded!'))
);
EDIT
Some of the commenters asked how to make sure that the last error is the one that gets thrown. The answer is a bit less clean but no less powerful, just use one of the flattening map operators (concatMap, mergeMap, switchMap) to check which index you are at.
Note: Using the new RxJS 6 pipe
syntax for future proofing (this is also available in later versions of RxJS 5).
loadSomething(): Observable<SomeInterface> {
const retryPipeline =
// Still using retryWhen to handle errors
retryWhen(errors => errors.pipe(
// Use concat map to keep the errors in order and make sure they
// aren't executed in parallel
concatMap((e, i) =>
// Executes a conditional Observable depending on the result
// of the first argument
iif(
() => i > 10,
// If the condition is true we throw the error (the last error)
throwError(e),
// Otherwise we pipe this back into our stream and delay the retry
of(e).pipe(delay(500))
)
)
));
return this.http.get(this.someEndpoint, commonHttpHeaders())
// With the new syntax you can now share this pipeline between uses
.pipe(retryPipeline)
}
Upvotes: 89
Reputation: 354
Use
.retry(3)
Repeats the source observable sequence the specified number of times or until it successfully terminates.
https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/retry.md
Upvotes: -13