Louis M.
Louis M.

Reputation: 5

Angular: Is there a way to simplify this subscription within a subscription?

I'm receiving a list of cart items from a service subscription and I want to take each CartItem object in that list and use one of its fields as a parameter for another service call ... which returns its own list, a list of products. Here's the code representation:

  cartItems: CartItem[];
  products: Product[];
    
  fetchCartItems() {
    this.cartService.getCartItemsList().subscribe(
      cartItems => {
        this.cartItems = cartItems

        for (let cartItem of this.cartItems) {
          // find the product with the cartItem's product_id
          this.productService.getProduct(cartItem.product.id).subscribe(
            product => { this.products.push(product); }
          );
        }
      }
    );
  }

Is there a better way of doing this?

Upvotes: 0

Views: 101

Answers (2)

Mrk Sef
Mrk Sef

Reputation: 8062

This is probably the most 1-1 translation of the code you've written without nesting subscriptions.

That being said, you can likely exchange the mergeMap for a switchMap, and perhaps even change merge(...array) for forkJoin(array) depending on your desired behaviour(s).

fetchCartItems() {
  this.cartService.getCartItemsList().pipe(
    mergeMap(cartItems  => merge(
      ...cartItems.map(cartItem => 
        this.productService.getProduct(cartItem.product.id)
      )
    ))
  ).subscribe(product => {
    this.products.push(product);
    console.log(product);
  });
}

Upvotes: 0

Lambo14
Lambo14

Reputation: 251

Subscription should never be nested instead you should use a flattening operator. I have created a sample implementation CodeSandbox

subs: Subscription;

  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.subs = this.http
      .get("https://dog.ceo/api/breeds/list/all")
      .pipe(
        switchMap(({ message }) => {
          console.log(message);
          return this.http.get("https://dog.ceo/api/breeds/image/random");
        })
      )
      .subscribe(console.log);
  }

  ngOnDestroy() {
    this.subs.unsubscribe();
  }

Upvotes: 1

Related Questions