angularrxjsfork-join

forkJoin get request value


I am trying to call multiple APIs using forkJoin. I believe the order in which the results will be return can be random. Is it possible to know which result belongs to which request?

Existing code:

interface Data {
  id: number, 
  input1: number,
  input2: number,
  sum?: number
}

arrayOfData : Data[] = [{id:1, input1: 5, input2: 3}, {id:2, input1: 2, input2: 4}, {id:3, input1: 1, input2: 4}];

let requests: Observable<Data>[] = [];

calculateSum(d:Data) : Observable<Data>{
     return this.callAPI(d);
}

let arrayOfData.forEach(d => {
  requests.push(this.calculateSum(d));
});

forkJoin(requests).subscribe(results => {
   // results : [{sum: 6}, {sum: 8}, {sum: 5}]
   // result only has sum, it does not include id. 
   // how can I assign this back to the correct array item of Data?
 
});

Should I use another operator instead of forkJoin?


Solution

  • If the API doesn't return the id with the response, you have to keep track of it yourself. forkJoin is ordered, so this is quite easy to manage with the map operator.

    Try this:

    interface Data {
      id: number, 
      input1: number,
      input2: number,
      sum?: number
    }
    
    arrayOfData: Data[] = [{id:1, input1: 5, input2: 3}, {id:2, input1: 2, input2: 4}, {id:3, input1: 1, input2: 4}];
    
    calculateSum(d:Data) : Observable<Data>{
         return this.callAPI(d);
    }
    
    let requests: Observable<Data>[] = arrayOfData.map(d => this.calculateSum(d))
    
    forkJoin(requests)
    .pipe(
        map(results => results.map((r, i) => ({ ...r, id: arrayOfData[i].id })))
    )
    .subscribe(results => {
       // results : [{id: 1, sum: 6}, {id: 2, sum: 8}, {id: 3, sum: 5}]
    });