Reputation: 1133
I've seen a dozen ways to implement retry strategies, and I feel like I'm really close. What I have here doesn't throw an error after takeWhile()
completes.
getItems(): Observable<ListItem[]> {
return this.authHttp.get(URL + '/items')
.retryWhen(e =>
e.scan((errorCount, err) => errorCount + 1, 0)
.takeWhile(errorCount => errorCount < 4)
.delay(3000))
.map(this.dataService.extractData)
.catch(err => this.dataService.handleError(err, 'The items could not be retrieved.'))
}
I've seen some jagged looking code snippets that might get it done. I experimented with inserting a .finally()
before the .delay()
.
Once I get this one solved, I'll want to pass the errorCount back up to my subscription so that I can display something useful. "Retry 1 of 4." Something to let the user know what is going on.
Upvotes: 3
Views: 1941
Reputation: 58430
With retryWhen
there are several things you can do with the observable passed to the notifier. You can:
In using takeWhile
, you're emitting notifications and are then completing - which sees the retries cease with no error.
It sounds like you want to emit the notifications, but then throw an error:
getItems(): Observable<ListItem[]> {
return this.authHttp.get(URL + '/items')
.retryWhen(e => e.scan((errorCount, error) => {
if (errorCount >= 4) {
throw error;
}
return errorCount + 1;
}, 0)
.delay(3000)
)
.map(this.dataService.extractData)
.catch(err => this.dataService.handleError(err, 'The items could not be retrieved.'));
}
To compartmentalize the retry logic into a reusable function, you can use the let
- "let me have the whole observable" - operator:
import 'rxjs/add/operator/let';
function handleRetry<T>(source: Observable<T>): Observable<T> {
return source.retryWhen(e => e.scan((errorCount, error) => {
if (errorCount >= 4) {
throw error;
}
return errorCount + 1;
}, 0)
.delay(3000)
);
}
getItems(): Observable<ListItem[]> {
return this.authHttp.get(URL + '/items')
.let(handleRetry)
.map(this.dataService.extractData)
.catch(err => this.dataService.handleError(err, 'The items could not be retrieved.'));
}
Upvotes: 3