typescript - Opérateurs pipables combinés avec RxJS/Angular
Est-il possible (je ne trouve rien de complet à ce sujet) de combiner plusieurs opérateurs pouvant être enchaînés dans une seule fonction, afin que je puisse l’enchaîner et la réutiliser dans une méthode différente également ?
Voici la chose :
public ngOnInit(): void {
this.route.url
.pipe(
switchMap( (ids: UrlSegment[]) => /* http call */),
tap(result => /* setting a variable within a service */),
tap(result => /* some more manipulating and logic */),
map(result => /* setting a _this_ variable */)
)
.subscribe( () => {
/* some other async tasks, which depend on _this_ variables */
this.cdr.detectChanges();
});
}
Comment puis-je extraire tout ce qui se trouve à l'intérieur de pipe() afin de pouvoir appeler la même chaîne d'opérateurs à partir d'une autre méthode, qui aurait besoin d'effectuer le même appel http et la logique et la manipulation ultérieurs ?
Ce que j'essaie d'atteindre est :
this.route.url
.pipe(
this.combinedPipableMethod(url: UrlSegment[])
)
.subscribe()
Réponse #1
Vous pouvez utiliser la fonction rxjs pipe (Remarque, c'est une fonction autonome, pas la méthode de l'Observable) pour combiner une séquence d'opérateurs en un opérateur réutilisable.
import { pipe } from "rxjs";
const customPipable = pipe(
switchMap( (ids: UrlSegment[]) => /* http call */),
tap(result => /* setting a variable within a service */),
tap(result => /* some more manipulating and logic */),
map(result => /* setting a _this_ variable */)
)
this.route.url
.pipe(customPipable)
.subscribe()
Voici un article à ce sujet
Réponse #2
Vous pourriez extraire une méthode :
getData(ids: UrlSegment[]) {
return this.http.get(/* url construction logic */)
.pipe(
tap(result => /* setting a variable within a service */),
tap(result => /* some more manipulating and logic */),
map(result => /* setting a _this_ variable */)
);
}
Et ensuite switchMap vers celui-ci :
public ngOnInit(): void {
this.route.url
.pipe(
switchMap(this.getData),
)
.subscribe( () => {
/* some other async tasks, which depend on _this_ variables */
this.cdr.detectChanges();
});
}
Sinon, vous pourriez créer un opérateur personnalisé, mais cela semble exagéré pour cet usage :
const combinedPipableMethod = () => {
return source => defer(() => {
return source.pipe(
switchMap((ids: UrlSegment[]) => /* http call */),
tap(result => /* setting a variable within a service */),
tap(result => /* some more manipulating and logic */),
map(result => /* setting a _this_ variable */)
)
})
}
public ngOnInit(): void {
this.route.url
.pipe(
combinedPipableMethod(),
)
.subscribe( () => {
/* some other async tasks, which depend on _this_ variables */
this.cdr.detectChanges();
});
}
