2016-07-27 3 views
1

Ich bin relativ neu in Angular 2, TypeScript und RxJS und erstelle eine einfache Anwendung, die die Salesforce Ajax Toolkit-Verbindungsbibliothek nutzt.RxJS warte auf zweite Observable und versuche dann die ursprüngliche Observable auf Fehler - TypeScript/Angular 2

Ich versuche, einen Handler zu schreiben, um zu fangen, wenn ein Token jedes Mal abgelaufen ist, wenn eine Methode aus der Verbindungsbibliothek aufgerufen wird. Ich habe einen Dienst erstellt, der im Wesentlichen die Verbindungsbibliothek für die Verwendung von Observablen umschließt. Zum Beispiel, wenn wir an der Insert-Funktion sehen ich habe meine eigene Wrapper-Funktion erstellt:

public insert(object: sforce.SObject): Observable<any> { 
    return new Observable(observer => { 
    // successfully inserted the record 
    let insertSuccess = (result) => { 
    observer.next(result); 
    observer.complete(); 
    } 

    // An error occured inserting the record 
    let insertError = (result) => { 
     // This does not work yet 
     if (result.faultcode.indexOf('INVALID_SESSION_ID') != -1) { 
     this.refreshToken(); 
     } 
     else { 
      observer.error(result); 
     } 
    } 

    let callback = { onSuccess: insertSuccess, onFailure: insertError }; 
    sforce.connection.create([object], callback); 
    }); 
} 

habe ich eine andere Funktion, die die Zugriffstoken aktualisiert:

public refreshToken(): void { 
    this.loginService.login().subscribe(
     response => { 

      Globals.SESSION_TOKEN = response.access_token; 

      //initialize the salesforce connection 
      this.init(Globals.SESSION_TOKEN, this.loginService.AuthParams.SOAP_URL); 
     }, 
     error => { 

     } 
    ); 
} 

ich im Wesentlichen die ursprüngliche insert Funktion warten soll, für refreshToken zu vervollständigen. Wenn es erfolgreich ist, möchte ich die gleiche Einfügung erneut versuchen, sonst möchte ich die ursprüngliche Einfügung beobachtbar observer.error aufrufen.

Ich habe sehe in retry und retryWhen, aber ich habe nicht in der Lage gewesen, um herauszufinden, wie es zu implementieren zu warten, die refreshToken() Funktion abzuschließen. Jede Anleitung oder Beratung in dieser Angelegenheit würde sehr geschätzt werden. Vielen Dank im Voraus.

Antwort

1

Der Operator catch akzeptiert eine Funktion, die einen Fehler verarbeitet und die Quelle Observable. Das bedeutet, dass, wenn Sie einen Fehler abfangen können Sie feststellen, ob Sie auf die ursprüngliche Quelle im catch Block resubscribe wollen:

public insert(object: sforce.SObject): Observable<any> { 
    return new Observable(observer => { 
    // successfully inserted the record 
    let insertSuccess = (result) => { 
    observer.next(result); 
    observer.complete(); 
    } 

    // An error occured inserting the record 
    let insertError = (result) => observer.error(result); 


    let callback = { onSuccess: insertSuccess, onFailure: insertError }; 
    sforce.connection.create([object], callback); 
    }).catch((err, source) => { 
    if (err.faultcode.indexOf('INVALID_SESSION_ID') != -1) { 
     //This waits for the refresh to complete and then resubscribes 
     //to the source 
     //If the refresh errors then it will skip the resubscribe 
     return this.refreshToken().flatMapTo(source); 
    } 
    //Non-authentication error 
    return Observable.throw(err); 
    }); 
} 

Dann Ihre refreshToken Funktion in etwas machen wie so:

public refreshToken(): Observable<any> { 
    return this.loginService.login() 
     .tap(response => { 
     Globals.SESSION_TOKEN = response.access_token; 

     //initialize the salesforce connection 
     this.init(Globals.SESSION_TOKEN, this.loginService.AuthParams.SOAP_URL); 
     }); 
} 
+0

Vielen Dank für die Antwort @paulpdaniels! Kannst du erklären, was tap tut? 'this.loginService.login' gibt ein' http.post' zurück. Ich erhalte den Fehler 'this.loginService.login (...). Tap ist keine Funktion' – ThreadedLemon

+1

' tap' führt einen Nebeneffekt auf Ereignisse im Stream aus, während sie trotzdem durchgelassen werden. Wahrscheinlich müssen Sie den Operator mit 'import' rxjs/add/operator/tap'' einbeziehen – paulpdaniels

Verwandte Themen