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