Reputation: 323
I have a dynamic array of Ajax URLs and trying to queue the calls in sequence. After finishing the first call successfully, the second ajax call will go or if the result is failed then it will end the execution loop. Like that it should complete the array until the end.
Do we have options for this with RxJS observables?
Upvotes: 2
Views: 1019
Reputation: 365
Example where data is fetched sequentially using concatMap
but processed asynchronously using mergeMap
.
import { from } from "rxjs";
import { concatMap, map, catchError, tap, mergeMap } from "rxjs/operators";
const urls = [
"https://randomuser.me/api/",
"https://geek-jokes.sameerkumar.website/api",
"https://dog.ceo/api/breeds/image/random"
];
from(urls)
.pipe(
concatMap(url => {
console.log("=>Fetch data from url", url);
return fetch(url);
}),
tap(response => console.log("=<Got reponse for", response.url)),
mergeMap(response => response.json()),
tap(data => console.log("Decoded response", data))
)
.subscribe(
() => console.log("fetched and decoded"),
e => console.log("Error", e),
() => console.log("Done")
);
Upvotes: 2
Reputation: 14169
Sure, concat
is the right creation function for that job. It is passed a list of Observables and completes them in order, one after the other. If any one of them fails, an error notification is sent that can be handled in the subscribe
function. The chain is completed immediately after an error, preventing subsequent Ajax calls to be fired.
An example could look like this:
concat(...urls.map(
url => this.http.get(url))
).subscribe(
next => console.log("An Ajax call has finished"),
error => console.log("An Ajax call has gone wrong :-( "),
complete => console.log("Done with all Ajax calls")
)
The documentation for concat
reads:
Creates an output Observable which sequentially emits all values from given Observable and then moves on to the next.
Upvotes: 1