I'm new to Angular and right now I'm using Angular 14 and I have a problem that happens to me often.
For example, I have an array and I make a for loop to go through each of its indexes and I make a POST call. The call and the functionality of the call are in a service and there I manage the result.
The problem I encounter is when below that for I have another http call that has to be executed when all the for calls have finished.
How can I perform this task?
for (let entrie of entries) {
this.service.callPost(entrie);
}
// Only when all the for calls have finished
this.service.callFinal();
I have seen that one option is to use forkJoin and store each call in an observable array and execute the final function within the forkJoin.
Thank you very much for the help.
I want to perform this type of operation since I perform an update of several data (for calls) and when these finish based on whether one gave an error or not the final call updates in one way or another, but the problem is that being asynchronous the final call does not wait for the for calls to finish.
I'm new to Angular and right now I'm using Angular 14 and I have a problem that happens to me often.
For example, I have an array and I make a for loop to go through each of its indexes and I make a POST call. The call and the functionality of the call are in a service and there I manage the result.
The problem I encounter is when below that for I have another http call that has to be executed when all the for calls have finished.
How can I perform this task?
for (let entrie of entries) {
this.service.callPost(entrie);
}
// Only when all the for calls have finished
this.service.callFinal();
I have seen that one option is to use forkJoin and store each call in an observable array and execute the final function within the forkJoin.
Thank you very much for the help.
I want to perform this type of operation since I perform an update of several data (for calls) and when these finish based on whether one gave an error or not the final call updates in one way or another, but the problem is that being asynchronous the final call does not wait for the for calls to finish.
Share Improve this question asked Feb 15 at 10:16 Sergio CeaSergio Cea 132 bronze badges2 Answers
Reset to default 0You can use forkJoin
and switchMap
for that:
import { forkJoin } from 'rxjs';
import { switchMap, catchError } from 'rxjs/operators';
let entries: string[];
// Fork join will wait for every given observable to finish before calling next.
const observable = forkJoin(
entries.map(entry => this.service.callPost(entry))
).pipe(
// switchMap will switch to an other Observable when forkJoin completes.
switchMap(results => this.service.callFinal().pipe(
catchError(error => {
// Handle the error
})
))
);
This will create an observable that will send a POST call for every entry of the entries
array and that will call final
afterward.
Note that you need to subscribe to this observable to start the process, either by calling it directly or by using the async
pipe.
observable.subscribe({
next: () => {
// Success!
},
error: reason => {
// Tell the user something went wrong.
}
});
It depends on your service code
Lets say you callPost
ist returning a promise then add await
to you code
for (let entrie of entries) {
await this.service.callPost(entrie);
}
// Only when all the for calls have finished
await this.service.callFinal();
Lets say you are returning the observable
for (let entrie of entries) {
await lastValueFrom(this.service.callPost(entrie));
}
// Only when all the for calls have finished
await lastValueFrom(this.service.callFinal());
Please notice in this case no subscribe
is needed and i guess this is your problem. you cannot await the subscribe. In this case you needed to transform the observable to promise as written above.
This is something you should already to in the service.