web-dev-qa-db-fra.com

angular2 - Naviguez une fois l'observable terminé

J'ai une http observable comme ceci, dans ma 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;
        });
}

J'ai créé un observable et créé un abonnement (response) qui correspond à la valeur de réussite renvoyée.

Maintenant, dans mon composant, je veux appeler UserService.logout() et ALORS naviguer vers un nouvel itinéraire:

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

Évidemment, cela pourrait se produire de manière asynchrone et je pourrais finir par naviguer avant de me déconnecter.

En utilisant des promesses, je pourrais faire quelque chose comme ceci:

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

Comment puis-je faire la même chose avec les observables? Dans ma classe UserService, je veux créer un observable, m'y abonner, faire des choses en cas de succès ou d'erreur, ALORS naviguer depuis mon composant de vue.

15
JMac

Vous pouvez réellement faire en sorte que la méthode logout renvoie une promesse et l’utilise normalement. Il n'est pas nécessaire que ce soit observable:

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

L'objet observable a enfin une méthode, essayez-le .

import 'rxjs/operators/finally';

Votre déconnexion () serait:

 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 ----

    });
  }

Si vous vouliez vraiment utiliser la promesse:

import 'rxjs/add/operator/toPromise';

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

dans composant.ts

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

Vous ne pouvez pas attendre que Observable se termine, car son flux pourrait continuer indéfiniment. Mais vous pouvez appeler router.navigate dans la méthode subscribe:

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']);
    });
  }

Si cela ne suffit pas, subscribe renvoie une Subscription dont la méthode unsubscribe cesse d'attendre les données de Observable. Donc, si vous devez le faire, vous pouvez attendre un délai et appeler unsubscribe.

0
MatthewScarpino

La déconnexion doit renvoyer un observable et non un abonnement ..__ Par exemple:

    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.)

Pour plus d'informations sur les opérateurs/méthodes: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md

0
nakuzm