typescript - Operadores encadeáveis combinados com RxJS/Angular
É possível (não consigo encontrar nada abrangente sobre isso) combinar múltiplos operadores encadeáveis em uma única função, para que eu possa encadeá-la e reutilizá-la em um método diferente também?
Aqui está a coisa:
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();
});
}
Como faço para extrair tudo dentro de pipe() para que eu possa chamar a mesma cadeia de operadores de um método diferente, que precisaria executar a mesma chamada http e a lógica subsequente e manipulação?
O que eu tento alcançar é:
this.route.url
.pipe(
this.combinedPipableMethod(url: UrlSegment[])
)
.subscribe()
Resposta #1
Você pode usar a função pipe do rxjs (Observe, é uma função independente, não o método do Observable) para combinar uma sequência de operadores em um único operador reutilizável.
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()
Aqui está um artigo sobre isso
Resposta #2
Você poderia extrair um método:
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 então switchMap para ele:
public ngOnInit(): void {
this.route.url
.pipe(
switchMap(this.getData),
)
.subscribe( () => {
/* some other async tasks, which depend on _this_ variables */
this.cdr.detectChanges();
});
}
Caso contrário, você poderia criar um operador personalizado, mas isso parece exagero para este propósito:
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();
});
}
