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 :
- Intercept HTTP request errors
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;
}