I am trying to reproduce the following behaviour that I successfully implemented using Angular 1.x interceptors and promises, in a Angular2 based Ionic2 app :
If the status code is 401, then
a. make another request to register the client. This will provide some token that I can subsequently attach to each request.
b. Retry the orignal request and provide the result to the caller through the promise / observable
If the error status is anything other than 401 just let the flow normally to the caller
NB: The register process does not need any intervention from the user (no login) so I want it to be completely transparent for the user. I register once when the app is first loaded, but the session will eventually expire and I need to automatically re-register.
This is the original Angular 1 implementation (I include only the responseError
part of the interceptor):
responseError : function(rejection){
if(rejection.status == 401){
$log.info('Intercepting unauthorized 401 response. Will try to re-register the session and retry the request.');
var security = $injector.get('SecurityService');
var $http = $injector.get('$http');
return security.registerSession().then(function(){
return $http(rejection.config);
});
}else{
return rejection;
}
}
Now, I have wrapped Angular2's HTTP service and I can do simple things like adding a header to each request. However I am struggling to reproduce the same behaviour using Angular2 and Observables.
My attempt so far, this is the request method of my HTTP wrapper that my services will call :
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
let req: Request = this.buildRequest(url, options);
this.beforeCall(req);
var observable = this.http
.request(req)
.retry(3)
.catch(res => {
debugger;
console.log("ERROR! " + res.status);
if(res.status == 401){
this.logger.log('Unauthorized request. Trying to register the session and then retry the request.');
return this.securityService.registerSession().subscribe(() => {
// What to do here so the client gets the result of the original request ??
});
}
})
.do((res:Response) => { this.afterCall(req, res) });
return observable;
}
Angular 2 applications have the option of error handling. This is done by including the ReactJS catch library and then using the catch function. Let's see the code required for error handling. This code can be added on top of the chapter for CRUD operations using http.
One traditional way of handling errors in Angular is to provide an ErrorHandler class. This class can be extended to create your own global error handler. This is also a useful way to handle all errors that occur, but is mostly useful for tracking error logs.
HttpErrorResponselink A response that represents an error or failure, either from a non-successful HTTP status, an error while executing the request, or some other failure which occurred during the parsing of the response.
You could execute again the request after initialize the session using the flatMap operator of observables:
var observable = this.http
.request(req)
.retry(3)
.catch(res => {
debugger;
console.log("ERROR! " + res.status);
if(res.status == 401){
this.logger.log('Unauthorized request. Trying to register the session and then retry the request.');
return this.securityService.registerSession().flatMap(() => {
return this.http.request(req); // <--------
});
}
})
.do((res:Response) => { this.afterCall(req, res) });
return observable;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With