4

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

4
  • 2
    Try using combineLatest() which ensures every observable emits at least 1 value: learnrxjs.io/learn-rxjs/operators/combination/combinelatest Commented Jul 16, 2020 at 14:42
  • As i am new to angular can u give a basic code for the above example with this combineLatest() Commented Jul 16, 2020 at 14:48
  • 1
    I already posted as an answer with using tap pipeable operator. Commented Jul 16, 2020 at 14:49
  • ok thanks,let me try this Commented Jul 16, 2020 at 14:55

2 Answers 2

6

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

Sign up to request clarification or add additional context in comments.

6 Comments

thanks for the answer and it is working for 4 request but i need this as dynamic.For example, that request array is a dynamic array,the number of request will be vary so i tried by adding all the request in an array and tried loop inside CombineLatest but it is showing syntax issue,can i write some loop inside CombineLatest????
Updated the answer to cover your need and added a stackblitz project link.
this is working perfectly,Thanks again,,, i did a small change in the code and i am just adding that down
Thanks, working perfect on Angular8. Also, thanks for the update, that's the version I'm using.
Perfect example for me as I have multiple type of Observables to listen at individual as well as combined level
|
0

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

1 Comment

You can simplify array creation like: let httpArray = param.map(p => this.http.post<any>( `${url}/PostDataSet?Id=${p}`, {}, httpOptions))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.