2016-01-28 7 views
24

Ich arbeite an einer Angular 2-App und benötige Anweisungen zur korrekten Behandlung von Authentifizierungsfehlern.Angular 2 - Mehrere Subskriptionen mit einer einzigen beobachtbaren Nummer behandeln

Mein Endziel ist in der Lage, Authentifizierungsfehler (speziell 401 und 403) für jede Anforderung Http zentral zu behandeln.

Ich fand this Frage super hilfreich, um mich zu starten, aber ich bin fest, wie der richtige Weg zur Registrierung meiner Fehlerbehandlung für jede beobachtbare von meiner benutzerdefinierten Http Implementierung zurückgegeben. Hier

ist eine Probe von dem, was ich gerade arbeite mit:

import {Injectable} from 'angular2/core'; 
    import {Http, ConnectionBackend, Request, RequestOptions, RequestOptionsArgs, Response} from 'angular2/http'; 

    import {Observable} from 'rxjs/Observable'; 


    @Injectable() 
    export class ClauthHttp extends Http { 

    constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) { 
     super(backend, defaultOptions); 
    } 

    get(url: string, options?: RequestOptionsArgs): Observable<Response> { 
     var response = super.get(url, options); 

     return this._handleSecurityResponse(response); 
    } 

    /* 
    Other overrides omitted for brevity... 
    */ 

    private _handleSecurityResponse(response: Observable<Response>):  Observable<Response> { 
     response.subscribe(null, (error: Response) => { 
      // Do some nifty error handling here. 
     }); 

     return response; 
    } 
} 

Die obige Lösung „arbeitet“ mit einem Haken ... Jede HTTP-Anforderung wird zweimal gemacht. Das ist nicht gut.

Irgendwelche Anleitungen, wie man das richtig macht?

(Update) Working-Code

Basierend auf den Informationen in der akzeptierten Antwort hier ist das, was die Klasse wie in seiner gut funktionierenden Form aussieht.

import {Injectable} from 'angular2/core'; 
    import {Http, ConnectionBackend, Request, RequestOptions, RequestOptionsArgs, Response} from 'angular2/http'; 

    import {Observable} from 'rxjs/Observable'; 
    import 'rxjs/add/operator/share'; 


    @Injectable() 
    export class ClauthHttp extends Http { 

    constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) { 
     super(backend, defaultOptions); 
    } 

    get(url: string, options?: RequestOptionsArgs): Observable<Response> { 
     var response = super.get(url, options); 

     return this._handleSecurityResponse(response); 
    } 

    /* 
    Other overrides omitted for brevity... 
    */ 

    private _handleSecurityResponse(response: Observable<Response>):  Observable<Response> { 
     var sharable = response.share(); 

     sharable.subscribe(null, (error: Response) => { 
      // Do some nifty error handling here. 
     }); 

     return sharable; 
    } 
} 

Antwort

29

Dies ist wahrscheinlich auf die Tatsache zurückzuführen ist, dass Ihre Observable<Response> eine Erkältung zu beobachten ist, das heißt es wird für jeden neuen Teilnehmer ‚neu gestartet‘. Für eine Erklärung der heißen und kalten Observablen, schauen Sie sich Hot and Cold observables : are there 'hot' and 'cold' operators? an. Also hier abonnieren Sie wahrscheinlich einmal für den Ergebnishandler und ein anderes Mal für den Fehlerhandler.

Sie sollten die Abonnements Nebeneffekt zu umgehen, indem Sie 'teilen' Ihre beobachtbare der Lage sein,

dh

ersetzen
var response = super.get(url, options); 

Mit

var response = super.get(url, options).share();` 
+0

Thanks..this ist genau das, was ich war Auf der Suche nach – prash