J'ai une fonction qui renvoie observable et je dois rediriger vers la page d'accueil si cette observable renvoie des données ou une erreur. Quelque chose comme ça:
private initializeCurrentUser() { this.userService .initializeCurrentUser() .subscribe( () => this.router.navigate(['']), //next () => this.router.navigate(['']) //error ); }
Existe-t-il un moyen de généraliser les appels next () et error () pour éviter la duplication de code?
3 Réponses :
Vous pouvez utiliser l'opérateur code> CatchError CODE>. L'opérateur gère des erreurs dans une séquence observable et des retours observables, donc vous abonnez-vous uniquement à la valeur suivante.
Par exemple: P>
private initializeCurrentUser() { this.userService .initializeCurrentUser() .pipe(catchError(() => of())) .subscribe(() => this.router.navigate([''])); }
Vous pouvez utiliser l'opérateur finalize
:
private initializeCurrentUser() { this.userService .initializeCurrentUser() .pipe(finalize(() => this.router.navigate(['']))) .subscribe(() => {}); }
Je pense que la réponse est non, vous ne pouvez pas généraliser next
et error
car subscribe
attend des rappels pour chacun. Il y a quelques options, mais je pense qu'elles sont plus codées et moins claires. Examinons-en un et voyons pourquoi.
Observable.subscribe
peut être appelé de deux manières différentes. La première consiste à transmettre les rappels pour suivant
, error
et complete
comme vous l'avez fait ci-dessus. Une autre consiste à lui passer un objet Observer
. Cet objet Observer
vous permettra de faire quelque chose comme ce que vous demandez.
Créons un Observer
qui a une méthode pour suivant qui gère votre redirection, et une méthode pour
error
qui appelle simplement next
.
private redirectToHomepage() { this.router.navigate(['']); } private initializeCurrentUser() { this.userService .initializeCurrentUser() .subscribe( () => this.redirectToHomepage(), //next () => this.redirectToHomepage() //error ); }
Maintenant, nous pouvons utilisez cela dans votre exemple original en passant ceci à Observable.subscribe()
private initializeCurrentUser() { this.userService .initializeCurrentUser() .subscribe(redirectObserver); }
Cela fonctionnera! Lorsque le Observable
émet des erreurs ou des erreurs, l'appel à la méthode de navigation du routeur se déclenchera. Mon argument contre cela est que généralement next
et error
sont différents, et cette approche cache que nous rompons la convention. Même si nous voulons vraiment les gérer de la même manière, nous pouvons être très explicites à ce sujet.
Pourquoi ne pas extraire simplement la logique dupliquée vers une méthode d'assistance? Cela a le même résultat que ce que vous voulez faire, et permet au code et à l'intention d'être clairs.
const redirectObserver = { next() { this.router.navigate(['']) }, error() { this.next() } };
Maintenant, si vous voulez changer où va la redirection ou ajouter logique supplémentaire, il ne sera qu'à un seul endroit, la définition de redirectToHomepage
, au lieu de dans les deux next
et error
. Notre exemple précédent avait également cet avantage, mais maintenant nous sommes très explicites et il est facile de voir que nous nous attendons au même comportement lorsque next
ou error
est déclenché.
Exemples RXJS observables ici: https: // rxjs-dev .firebaseapp.com / api / index / class / Observable