webentwicklung-frage-antwort-db.com.de

angle2 - Navigiere, nachdem Observable abgeschlossen ist

Ich habe eine http-Observable so in meiner UserService:

logout() {
    return this.http.delete(this.baseUrl + url, {
          headers: this.headers()
        }).map((res: IResponse) => {
          var json = res.json();
          json.headers = res.headers;
          return json;
        }).subscribe((response) => {
          //DO SOMETHING, THEN ----
          return res;
        });
}

Ich habe ein Observable erstellt und ein Abonnement (response) erstellt, das den zurückgegebenen Erfolgswert darstellt.

Jetzt möchte ich in meiner Komponente UserService.logout() aufrufen und dann zu einer neuen Route navigieren:

logout() {
    this.userService.logout();
    this.router.navigate(['LandingPage']);
  }

Natürlich könnte dies asynchron passieren, und ich navigiere möglicherweise vor dem Abmelden.

Mit Versprechungen könnte ich so etwas tun:

this.userService.logout().then(() => { this.router.navigate(['LandingPage']); });

Wie kann ich dasselbe mit Observablen machen? In meiner UserService-Klasse möchte ich ein Observable erstellen, es abonnieren, etwas zum Erfolg oder zu Fehlern tun.

15
JMac

Sie können die logout-Methode tatsächlich dazu bringen, ein Versprechen zurückzugeben und es wie üblich zu verwenden. Es muss nicht beobachtbar sein:

logout() {
    return new Promise((resolve, reject) => {
        this.http.delete(this.baseUrl + url, { headers: this.headers() })
            .map((res: IResponse) => {
              var json = res.json();
              json.headers = res.headers;
              return json;
            })
            .subscribe(data => {
              //DO SOMETHING, THEN ----
              resolve(data);
            }, error => reject(error));
    });
}

logout() {
  this.userService.logout().then(response => this.router.navigate(['LandingPage']))
}
16
dfsq

Das beobachtbare Objekt hat eine Methode, probieren Sie es aus. Vergessen Sie nicht, zuerst zu importieren:

import 'rxjs/operators/finally';

Ihre Abmeldung () wäre:

 logout() {
  return this.http.delete(this.baseUrl + url, { headers: this.headers() })
    .map(res => res.json())
    .finally(() => this.router.navigate(['LandingPage']))
    .subscribe((response) => {
      //DO SOMETHING, THEN ----

    });
  }

Wenn Sie wirklich versprechen wollten:

import 'rxjs/add/operator/toPromise';

logout() {
  return this.http.delete(this.baseUrl + url, { headers: this.headers() })
    .map(res => res.json());

in komponente.ts

var aPromise = this.userService.logout().toPromise();
aPromise.then(() => {
    this.router.navigate(['LandingPage']);
});
7
codely

Sie können nicht warten, bis eine Observable beendet ist, da der Stream unbegrenzt fortgesetzt werden kann. Sie können jedoch router.navigate innerhalb der subscribe-Methode aufrufen:

logout() {
  return this.http.delete(this.baseUrl + url, { headers: this.headers() })
    .map((res: IResponse) => res.json())
    .subscribe((response) => {
      //DO SOMETHING, THEN ----
      this.router.navigate(['LandingPage']);
    });
  }

Wenn dies nicht ausreicht, gibt subscribe eine Subscription zurück, deren unsubscribe-Methode nicht mehr auf die Daten der Observable wartet. Wenn Sie müssen, können Sie auf eine Zeitüberschreitung warten und unsubscribe aufrufen.

0
MatthewScarpino

Für die Abmeldung muss ein Observable, kein Abonnement, zurückgegeben werden. __ Beispiel:

    logout(): Observable<T> {
        return this.http.delete(this.baseUrl + url, {
              headers: this.headers()
            }).map((res: IResponse) => {
              var json = res.json();
              json.headers = res.headers;
              return json;
            })
            .catch((err)=>Observable.empty()) // return empty if error
            .share(); // to ensure that no duplicate http calls can occur
 
    }

    //in component:

    this.service.logout()
      .do(()=>this.router.navigate(['LandingPage']);)//do stuff
      .subscribe((res:any)=>{});

    //or with template async pipe:

    public result$ = Observable<T>;

    result$ = this.service.logout()
      .do(()=>//do stuff);

    //in template:
 
    {{(result$ | async)?.id}}
    or simply
    {{result$ | async}}

    // P.s. do not forget about unsubscribe(), thats why I prefer to use async (since that's the Async pipe's job.)

Weitere Informationen zu Operatoren/Methoden: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md

0
nakuzm