Skip to content

Perform http request for every item in a previous request response with Rxjs

I’ve got a request that returns something like this get(‘/product-list)

[
{
product_id: 1,
description: 'product 1',
color_id: 1
},
{
product_id: 2,
description: 'product 2',
color_id: 2
},
...
]

To obtain de color_id information I have to perform another request to something like get(‘color/1’)

I want to obtain something like

{
product_id: 1,
description: 'product 1',
color_id: 1,
color_detail: {object_with_full_color_detail}
},

I was able to obtain it with something like this:

this.getProductList().subscribe(productList => {
  const detailsObservables = productList.map(product => {
    return this.getColorDetail(product.color_id);
  });
  forkJoin(colorObservables).subscribe(colorDetailResponses) {
    const productListWithColorInfo = productList.map((product, index) => {
      return {...product, color_info: colorDetailResponses[index]};
    });
  }
});

I tried mergeMap to resolve this in a single process, but i couldn’t perform the inner request for every item in the productList.

Any idea to resolve this?

Thanks in advance

Answer

MergeMap should work.

this.getProductList().pipe(

  // Create a request for each product
  map(productList => productList.map(product => 
    this.getColorDetail(product.color_id).pipe(

      // Map result of request and product together
      map((colorDetailResponses, index) => ({
        ...product,
        color_info: colorDetailResponses[index]
      }))
    )
  ),

  // Run the requests
  mergeMap(requests => forkJoin(requests))

).subscribe(
  productListWithColorInfo => 
    console.log("Received: ", productListWithColorInfo)
);

Combine Map and MergeMap

this.getProductList().pipe(
  mergeMap(productList => forkJoin(
    productList.map(product => 
      this.getColorDetail(product.color_id).pipe(
        map((colorDetailResponses, index) => ({
          ...product,
          color_info: colorDetailResponses[index]
        }))
      )
    )
  )
).subscribe(
  productListWithColorInfo => 
    console.log("Received: ", productListWithColorInfo)
);