Como faço uma nova chamada para uma api quando uma anterior foi concluída com êxito?
Eu sou novo no angular e rxjs, e tenho o seguinte cenário, em que preciso que, após uma chamada para uma api ser resolvida com sucesso para fazer uma nova chamada, no contexto do angular / rxjs não sei como fazer isto
handler(): void {
this.serviceNAme
.createDirectory(this.path)
.pipe(
finalize(() => {
this.someProperty = false;
})
)
.subscribe(
(data) => console.log(data),
(error) => console.error(error.message)
);
}
Qual é a maneira correta de fazer uma nova chamada para uma api quando uma anterior foi bem-sucedida?
Respostas
Eu entendo que você tem um serviceOne
e um serviceTwo
. E você deseja chamar serviceTwo
usando os dados recuperados de serviceOne
.
Usando rxjs switchMap, você pode canalizar um observável para outro.
handler(): void {
this.serviceOne
.createDirectory(this.path)
.pipe(
switchMap(serviceOneResult => {
// transform data as you wish
return this.serviceTwo.methodCall(serviceOneResult);
})
)
.subscribe({
next: serviceTwoResult => {
// here we have the data returned by serviceTwo
},
error: err => {},
});
}
Se você não precisa passar os dados de serviceOne
para, serviceTwo
mas precisa que ambos sejam concluídos juntos, você pode usar rxjs forkJoin .
handler(): void {
forkJoin([
this.serviceOne.createDirectory(this.path),
this.serviceTwo.methodCall()
])
.subscribe({
next: ([serviceOneResult, serviceTwoResult]) => {
// here we have data returned by both services
},
error: err => {},
});
}
Usando aysnc
e await
você pode fazer:
async handler(): void {
await this.serviceNAme
.createDirectory(this.path)
.pipe(
finalize(() => {
this.someProperty = false;
})
)
.subscribe(
(data) => console.log(data),
(error) => console.error(error.message)
);
// Do second api call
}
Existem alguns comandos para fazer isso:
Cenário 1
Suas duas chamadas de API de serviço são independentes, você só quer que uma vá e depois a próxima
const serviceCall1 = this.serviceName.createDirectory(this.path);
const serviceCall2 = this.serviceName.createDirectory(this.otherPath);
concat(serviceCall1 , serviceCall2).subscribe({
next: console.log,
error: err => console.error(err.message),
complete: () => console.log("service call 1&2 complete")
});
Cenário # 2
Suas duas chamadas dependem uma da outra, então você precisa do resultado da primeira antes de iniciar a segunda
this.serviceName.getDirectoryRoot().pipe(
switchMap(root => this.serviceName.createDirectoryInRoot(root, this.path))
).subscribe({
next: console.log,
error: err => console.error(err.message),
complete: () => console.log("service call 1 used to create service call 2, which is complete")
});
Você vai querer o cenário 2 , porque feito dessa forma, um erro na primeira chamada significará que nenhum resultado será enviado ao switchMap
e a segunda chamada nunca será feita.