user3501613
user3501613

Reputation: 610

Handle multiple API requests parallel from angular 8

I need to call multiple API request from my angular app parallel and i need to get each response separately(need to do some different actions for each response) and also i need to track when all the request finished the execution

for example i have an array of request arr1[request1,request2,request3,request4] and each request will take different time to get the response.so i need to do different actions like actn1,actn2,actn3..etc according to the response.i need to call each action in FCFS manner. some request will finish execution faster than other request so whenever i get response of each request i need to call corresponding action and finally after getting all response i need to call finalAction also.

By using forkJoin am able to execute my finalAction(after finished all request execution this has to work) but i don't know how i will execute each response action whenever the response came from the server

Upvotes: 3

Views: 11149

Answers (2)

user3501613
user3501613

Reputation: 610

I got the solution from @Harun Yilmaz post,Just i am adding that here for others reference.

getDataFromApi(url) {
    let httpOptions={};
    let param=["CAL3","CAL2","CAL1"];//dynamic parameter(CAL1:8sec,CAL2:5s,CAL3:12s)
    let httpArray=[];
for(let i=0;i<param.length;i++){
      httpArray.push(this.http.post<any>(url + `/PostDataSet?Id=${param[i]}`, {}, httpOptions))
   }
   const handleResponse = (response) => {
       //here i am getting each response in a first come first manner
       console.log(response.Table[0].Output);
      }
const combineResponse =combineLatest(
  httpArray.map(req => req.pipe(tap(handleResponse)))
   )
    return combineResponse;
}
//output
 CAL2
 CAL1
 CAL3

Upvotes: 0

Harun Yilmaz
Harun Yilmaz

Reputation: 8558

Try using combineLatest() which ensures every observable emits at least 1 value. And you can use .pipe() and tap() for any of the observables to take individual action.

combineLatest([

   req1.pipe(tap(result => {
     /* take action */
   })),

   req2.pipe(tap(result => {
     /* take another action */
   })),

   req3.pipe(tap(result => {
     /* take a super action */
   })),

   req4.pipe(tap(result => {
     /* do nothing maybe */
   }))

]).subscribe((resultArray) => {
  /* take the final action as all of the observables emitted at least 1 value */
})

combineLatest reference: https://www.learnrxjs.io/learn-rxjs/operators/combination/combinelatest

tap reference: https://www.learnrxjs.io/learn-rxjs/operators/utility/do


UPDATE

If you have a dynamic length of array, you can use Array.map() inside combineLatest() to iterate over observables

const requests = [req1,req2,req3,..., reqN]

combineLatest(
  requests.map(req => req.pipe(tap(res => handleResponse(res))))
).subscribe();

const handleResponse = (response) => { /*do something*/ }

Here's a working stackblitz project: https://stackblitz.com/edit/rxjs-a16kbu

Upvotes: 6

Related Questions