Reputation: 610
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
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
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