typescript - Angular2 : HTTP-felhantering
Jag försöker återskapa följande beteende som jag framgångsrikt implementerade med Angular 1.x-interceptorer och löften, i en Angular2-baserad Ionic2-app :
- Avlyssna HTTP-förfrågningsfel
Om statuskoden är 401, då
a. gör en annan begäran för att registrera klienten. Detta kommer att ge en token som jag därefter kan bifoga varje begäran.
b. Försök igen med den ursprungliga begäran och ge resultatet till anroparen genom löftet/observerbaren
Om felstatusen är något annat än 401, låt flödet bara fortsätta normalt till anroparen
OBS: Registreringsprocessen behöver ingen användarintervention (ingen inloggning) så jag vill att den ska vara helt transparent för användaren. Jag registrerar en gång när appen först laddas, men sessionen kommer så småningom att löpa ut och jag behöver automatiskt registrera igen.
Detta är den ursprungliga Angular 1-implementeringen (jag inkluderar endast responseError-delen av interceptorn):
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;
}
}
Nu har jag kapslat in Angular2:s HTTP-tjänst och jag kan göra enkla saker som att lägga till en header på varje förfrågan. Däremot har jag svårt att återskapa samma beteende med Angular2 och Observables.
Mitt försök hittills, detta är begäransmetoden i min HTTP-wrapper som mina tjänster kommer att anropa :
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;
}
Svar #1
Du kan utföra förfrågan igen efter att ha initierat sessionen med hjälp av flatMap-operatören för 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;
}
