Blake Rivell
Blake Rivell

Reputation: 13875

Subscribing to an observable within a pipe(map())

I am making an http call that returns an observable of a list of products. For each product I need to subscribe to an observable which contains the price (since it is a separate request from another service).

I think this is working, but not sure if this is how it should be done:

return this.httpService.get(url, config).pipe(map(res => res.data.map(product => {
   let price;
   this.productPriceService.getPriceByProductId(product.id).subscribe(value => price = value);
   return {
       id: product.id,
       name: product.name,
       price
   }
})));

I have also tried the following an I am getting a circular JSON reference error:

return this.httpService.get(url, config).pipe(map(res => res.data.map(product => {
   return {
       id: product.id,
       name: product.name,
       price: this.productApiService.getPriceByProductId(product.id).subscribe(value => price = value)
   }
})));

Upvotes: 0

Views: 1640

Answers (1)

Julian W.
Julian W.

Reputation: 1571

You should use a combination of switchMap and forkJoin operators.

The code should look like the following

return this.httpService.get(url, config).pipe(
  switchMap(
    res => forkJoin(
      res.data.map(product => this.productPriceService.getPriceByProductId(product.id).pipe(map(price => ({
        id: product.id,
        name: product.name,
        price
      }))))
    )
  )
);

getPriceByProductId function returns an observable, which is asynchronous. So you can't use map operator there. When you use map operator, it doesn't wait for that observable to finish and immediately returns the new data.

switchMap operator is creating another observable instance so that you can wait for the response of it too.

In one word, map returns a value and switchMap returns an observable.

Upvotes: 3

Related Questions