I want to call a number of API endpoints at once (asynchronously). I get an Observable from a single API call, and I want to "await" them all together, and get the results from each call to handle as a collection, preferably with an option to handle the exceptions (if any) from each one. Much like asyncio.gather() but for Angular. I don't want to convert the observables to promises, and I don't want to use deprecated methods such forkJoin() or the async pipe. Is there any other solution?
CodePudding user response:
forkJoin is actually not deprecated but some overrides of it are.
An array of Observables or a dictionary are valid inputs to forkJoin.
This shouldn't throw any warnings about deprecation.
const sources$: Observable<any>[] = [obs1$, obs2$, obs3$]
forkJoin(sources$).subscribe()
CodePudding user response:
So instead of 'converting' the observables to promises (I assume you're referring to toPromise()), you just wrap the subscriptions in promises. Then you use Promise.all() to await them concurrently.
constructor(private http: HttpClient) {}
async waitForResponses() {
const obs1 = this.http.get('api1');
const obs2 = this.http.get('api2');
const obs3 = this.http.get('api3');
const promise1 = new Promise((resolve) =>
obs1.subscribe((result) => resolve(result))
);
const promise2 = new Promise((resolve) =>
obs2.subscribe((result) => resolve(result))
);
const promise3 = new Promise((resolve) =>
obs3.subscribe((result) => resolve(result))
);
const [result1, result2, result3] = await Promise.all<any>([promise1, promise2, promise3]);
console.log(result1);
console.log(result2);
console.log(result3);
}
This awaits all api calls concurrently, but you could await them in any order you like.
Promise.all() returns an array of the results, at the same index as their respective promise. I'm pretty sure that's exactly what you're looking for.
Error handling:
const promise1 = new Promise((resolve, reject) =>
obs1.subscribe({
next: (result) => resolve(result),
error: (err) => reject(err),
})
).catch((err) => console.log(err));
