Reputation: 162
I have a typescript array this.products
I need to loop over the elements of the array and for each element send parameters to Angular service which makes an API call and gets an answer to the client as an Observable. However, due to asynchronous nature of Observable, my loop finishes before all of the answer are sent back from the server.
This is my code:
this.products.forEeach((ele, idx) => {
this.myService.getSomeDetails(ele.prop1, ele.prop2).subscribe(result => {
// do something with result
});
});
I need for the loop to advance only after the completion of each observable subscription. How can I implement it? Thanks.
Upvotes: 1
Views: 2262
Reputation: 365
This is good way to code it.
from(this.products).pipe(mergeMap(
ele => this.myService.getSomeDetails(ele.prop1, ele.prop2)
)).subscribe(result => {
() => console.log('.'),
e => console.error(e),
() => console.log('Complete')
});
Upvotes: 0
Reputation: 92677
Try this:
let results = await Promise.all(this.products.map(ele =>
this.myService.getSomeDetails(ele.prop1, ele.prop2).toPromise()
));
// put code to process results here
Requests are sent parallel. Rememeber to add async
keyword in function definition which use above code. More info here.
Upvotes: 0
Reputation: 6441
What you are looking for is forkJoin:
https://rxjs-dev.firebaseapp.com/api/index/function/forkJoin
Map your array of items to an array of api call observables, and pass them into forkJoin. This will emit an array of all your resolved api calls.
Quick and dirty example:
forkJoin(this.products.map(i => this.myService.getSomeDetails(ele.prop1, ele.prop2))).subscribe(arrayOfApiCallResults => {
// get results from arrayOfApiCallResults
})
Upvotes: 4
Reputation:
You don't need async/await keywords to make your call in sequence.
import { concat } from 'rxjs';
concat(this.products.map(ele => this.myService.getSomeDetails(ele.prop1, ele.prop2)))
.subscribe(
response => console.log(response),
error => console.log(error),
() => console.log('all calls done')
)
Upvotes: 2