I have an array of items which on each element I want to make an HTTP call, wait for it to finish, then make another call, only one at a time.
I tried:
index(item) {
return this.service.index(item).pipe(
map(response => {
// handle success case
}),
catchError(error => {
// handle error case
})
)
}
async processArray(array) {
const promises = array.map(item => this.index(item));
await Promise.all(promises);
}
proccessArray(array);
Also with NGRX Effects:
@Effect()
effect$ = this.actions$.pipe(
ofType<action>(actionTypes.action),
mergeMapTo(this.store.select(getMyArray)),
flatMap((request: any[]) => {
return zip(...request.map(item => {
return this.service.index(item).pipe(
map(response => {
// handle success case
}),
catchError(error => {
// handle error case
})
)
}))
}),
);
Also tried doing it in for
and forEach
loops but they fire all the requests at once. How could I achieve this?
I have an array of items which on each element I want to make an HTTP call, wait for it to finish, then make another call, only one at a time.
I tried:
index(item) {
return this.service.index(item).pipe(
map(response => {
// handle success case
}),
catchError(error => {
// handle error case
})
)
}
async processArray(array) {
const promises = array.map(item => this.index(item));
await Promise.all(promises);
}
proccessArray(array);
Also with NGRX Effects:
@Effect()
effect$ = this.actions$.pipe(
ofType<action>(actionTypes.action),
mergeMapTo(this.store.select(getMyArray)),
flatMap((request: any[]) => {
return zip(...request.map(item => {
return this.service.index(item).pipe(
map(response => {
// handle success case
}),
catchError(error => {
// handle error case
})
)
}))
}),
);
Also tried doing it in for
and forEach
loops but they fire all the requests at once. How could I achieve this?
- You can use recursive function here which will call itself after getting response for previous array item – Abhay Sehgal Commented Dec 25, 2018 at 13:58
-
1
Where are the HTTP calls you want make? In
request
? – martin Commented Dec 25, 2018 at 14:32
1 Answer
Reset to default 6If you are using promises and want to wait for each promise to resolve before another call is made then (1) you should not use Promise.all as this will wait til all requests are resolved and (2) you need to use a plain old for-loop which enables you to wait for async operations within the loop.
async processArray(array) {
for(var i = 0; i < array.length; i++){
await yourServiceCall();
}
}
As a sidenote: Since you are using async-await, don't forget to convert your observables to promises.
If you want to move away from promises (and async-await) and rely on pure RxJS instead, have a look at concatMap:
Projects each source value to an Observable which is merged in the output Observable, in a serialized fashion waiting for each one to plete before merging the next.
For example:
import { from } from 'rxjs/observable/from';
ngOnInit() {
from(myArray)
.pipe(concatMap(el => yourServiceCall(el)))
.subscribe(/* your logic */);
}