-1

I have a array of length 10 var a = [1, 2, 3, ....10]; // length=10;

how do I make 2 parallel Api call for same array length;

forkJoin([
  a.map(response => {
   return this.http.post('/api/1', response);
 }),
  a.map(response => {
  return this.http.post('/api/2', response)
  })
]
).subscribe(result => ) // i am getting [Observable, Observable] here
Michael D
  • 20,838
  • 4
  • 12
  • 37
  • 4
    The question isn't clear at the moment. Do you mean to call 2 different API end-points for each element in the array for a total of (2x10) 20 requests? – Michael D Jan 21 '21 at 14:43
  • This seems like a poor API design, frankly. Seems like the API should be able to take more than one item at a time. Otherwise, this is going to saturate your HTTP connections pretty quick. Most browsers throttle at a max of 4 connections at a time. – Heretic Monkey Jan 21 '21 at 14:49
  • @MichaelD: yes exactly 20 request 10 for first api call and 10 for second api call...in parallel. like call --> \api\1 call --> \api\2 – user2822322 Jan 22 '21 at 08:54

3 Answers3

1

You could use JS Array#flatMap to create an array containing both requests for each element in the array and altogether flatten them. That should result in 20 parallel requests with 2 requests for each element in the array.

forkJoin(
  arr.flatMap(item => [
    this.http.post(`/api1/{item}`, response),
    this.http.post(`/api2/{item}`, response)
  ])
).subscribe({
  next: res => {
    // `res` is an array with 20 elements each corresponding to it's respective response
  },
  error: error => {
    // handle error
  }
});

If you think flatMap (ES2019) might not be available is some browsers yet, you could use Array#map with the solution shown here to flatten the array.

forkJoin(
  [].concat.apply([],  // credit: https://stackoverflow.com/a/10865042/6513921
    arr.map(item => [
      this.http.post(`/api1/{item}`, response),
      this.http.post(`/api2/{item}`, response)
    ])
  )
).subscribe();

Update: include condition !order.price

You'd need to filter the undefined elements in the array introduced by the condition !order.price with Array#map.

forkJoin(
  [].concat.apply([],  // credit: https://stackoverflow.com/a/10865042/6513921
    arr.map(order => 
      !order.price 
        ? [
            this.http.post(`/api1/{item}`, response),
            this.http.post(`/api2/{item}`, response)
          ]
        : null
    )
  )
  .filter(item => !!item)  // <-- remove undefined/null elements
).subscribe();
Michael D
  • 20,838
  • 4
  • 12
  • 37
0

Your code

forkJoin([
  a.map(response => {
   return this.http.post('/api/1', response);
 }),
  a.map(response => {
  return this.http.post('/api/2', response)
  })
]
).subscribe(result[] =>{
          /*
          res[0][0] is the response to http.post('/api/1', 1)
          res[0][1] is the response to http.post('/api/1', 2)
          res[0][2] is the response to http.post('/api/1', 3)
          ...
    
          res[1][0] is the response to http.post('/api/2', 1)
          res[1][1] is the response to http.post('/api/2', 2)
          res[1][1] is the response to http.post('/api/2', 3)
          ...
          */

})

you can also

forkJoin(a.map(x=>forkJoin([
   this.http.post('/api/1', x),this.this.http.post('/api/1', x)])
   .subscribe(res[]=>{
      /*
      res[0][0] is the response to http.post('/api/1', 1)
      res[0][1] is the response to http.post('/api/2', 1)

      res[1][0] is the response to http.post('/api/1', 2)
      res[1][1] is the response to http.post('/api/2', 2)

      ...
      */
   })
Eliseo
  • 29,422
  • 4
  • 13
  • 37
  • ` forkJoin arr.map(order => { if (!order.price) { return forkJoin([ this.http.post('/api/1', order.ordernumber) this.http.post('/api/2', order.size) ]) } }) ` – user2822322 Jan 22 '21 at 08:59
  • But if order.price I think you should return an observable too. You can use "of" to return an array with two elements `else return of([null,null])`. So you don't lose the order in the array – Eliseo Jan 22 '21 at 09:09
  • Thanks for your comment it worked out as, in returning observable in else condition. – user2822322 Jan 22 '21 at 11:49
0

I have total 180 records. i am calling api in batch of 10 records. I did like this for 10 records api call is going but for another 10 record api call is not going...

const recodrd$ = forkJoin(
      arr.map(order => {
        if (!order.price) {
          return forkJoin([
            this.http.post('/api/1', order.ordernumber)
            this.http.post('/api/2', order.size)
          ])
        }
      })
).subscribe(result => {
    $records.unsubscribe();
 // getting result here for first 10 records.
})

but again when this function execute no api call is going.