I want to make a call to a server that can return an authorization fail (401) with Angular2\'s HTTP class.
The flow of the request should look like that:
I think that you need to return something an observable even in the case of the 401 error:
public errorHandler(res: Response, ob: Observable<any>): Observable<Response> {
if (res.status === 401) {
let closedSubject = new Subject();
this.modalService.open(new ModalConfig({
content: LoginModalComponent,
close: () => {
closedSubject.next();
}));
return ob.retryWhen(() => closedSubject);
}
else {
return Observable.throw(res.json());
}
}
See this article for more details: https://jaxenter.com/reactive-programming-http-and-angular-2-124560.html.
Edit
The problem is that the second parameter of the catch
callback isn't the source observable. This source observable corresponds to the value of its source
property:
return ob.source.retryWhen((errors) => closedSubject);
See the working plunkr: https://plnkr.co/edit/eb2UdF9PSMhf4Dau2hqe?p=preview.
I guess retryWhen
operator should help.
I believe the solution has changed a little, since in the news versions of Angular we must use the pipe()
method. So I decided to use a custom operator solution. One good thing is the handleError()
method could be exported as a global function and then be used in more than one service.
See this solution for more details: https://blog.angularindepth.com/retry-failed-http-requests-in-angular-f5959d486294
export class MyService {
// ...
public getSomething(): Observable<Response> {
return this.http.get(url, options).pipe(this.handleError('Maybe your a custom message here'));
}
private handleError(errorMessage: string) {
return (source: Observable<any>) => source.pipe(
retryWhen(errors => errors.pipe(
mergeMap((errorResponse: HttpErrorResponse) => {
console.error(errorMessage);
if (errorResponse.status === 401) {
const closedSubject = new Subject();
this.modalService.open(new ModalConfig({
content: LoginModalComponent,
close: () => {
closedSubject.next();
}
}));
return closedSubject;
}
return throwError(errorResponse);
})
))
);
}
}