typescript - Operatori pipabili combinati con RxJS/Angular
È possibile (non riesco a trovare niente di completo su questo) combinare più operatori pipabili in un'unica funzione, così posso usarla nel pipe e riutilizzarla anche in un metodo diverso?
Ecco la cosa:
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();
});
}
Come faccio a estrarre tutto ciò che si trova all'interno di pipe() in modo da poter chiamare la stessa catena di operatori da un metodo diverso, che dovrebbe eseguire la stessa chiamata HTTP e la logica successiva e le manipolazioni?
Quello che cerco di ottenere è:
this.route.url
.pipe(
this.combinedPipableMethod(url: UrlSegment[])
)
.subscribe()
Risposta n. 1
Puoi usare la funzione rxjs pipe (Nota, è una funzione autonoma, non il metodo dell'Observable) per combinare una sequenza di operatori in un singolo operatore riutilizzabile.
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()
Ecco un articolo a riguardo
Risposta n. 2
Potresti estrarre un metodo:
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 */)
);
}
E poi switchMap su di esso:
public ngOnInit(): void {
this.route.url
.pipe(
switchMap(this.getData),
)
.subscribe( () => {
/* some other async tasks, which depend on _this_ variables */
this.cdr.detectChanges();
});
}
Altrimenti, potresti creare un operatore personalizzato, ma sembra esagerato per questo scopo:
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();
});
}
