Home > database >  RXJS, how to change the result of each result from an observable?
RXJS, how to change the result of each result from an observable?

Time:10-27

I have this reloadProducts function that i use to reload the products i have in my cart. I have 2 models, one is CartProduct and the other a Product. The CartProduct has a name which i use with a function from my service, to get the matching Product.

Now when i map the cartProduct, i want to check if that CartProduct has a boolean (mixMatch) set to true, if so then set the Products mixMatch boolean to true and false if not. In the code below i commented #HERE with where i gave my try on it, but it's not working.

Can anyone help me or guide me in any direction on how to do this?

  @HostListener('window:storage')
  reloadProducts() {
    this.cartProducts = Array.from(this.cartService.getProducts());
    this.products = undefined;
    this.totalPrice = undefined;
    this.producers = undefined;
    this.producerNames = [];
  
    forkJoin(
      this.cartProducts.map(cartProduct => {
        let result = this.productService.getProduct(cartProduct.product_name);
         // HERE
        result.subscribe((product) => {
          if (cartProduct.mixMatch) {
            product.mixMatch = true;
          }
          else if (!cartProduct.mixMatch) {            
            product.mixMatch = false;
          }
        })
        return result;
      }
      )
    ).pipe(
      switchMap(productListDto => {
        productListDto.map(product => {
          if (this.producerNames.indexOf(product.producer_name) === -1) {
            this.producerNames!.push(product.producer_name)
          }
        })
        this.products = productListDto
        this.mixMatchProducts = productListDto.filter(p => p.mixMatch)

        return forkJoin(
          this.producerNames.map(producerName => this.producerService.getProducerByName(producerName))
        )
      })
    ).subscribe(producers => this.producers = producers)
    this.fetchTotalPrice();
    
  }

CodePudding user response:

You want to have the function form part of the rxjs pipeline, so I would rather pipe the result of getProduct through a map. I would do this as follows:

this.cartProducts.map(cartProduct => 
  this.productService
    .getProduct(cartProduct.product_name)
    .pipe(
      map((product) => {
        product.mixMatch = cartProduct.mixMatch;
        return product;
      })
    )
)

You could also use the tap function, with which you don't need to return the product.

CodePudding user response:

You code can be simplified as below near //HERE block:

        // HERE
        result.subscribe((product) => {
          console.log(cartProduct.mixMatch)
          if (cartProduct.mixMatch) {
            product['mixMatch'] = true;
          }
          else {            
            product['mixMatch'] = false;
          }
        })

if map() function is required, try this as well,

result.subscribe((product) => {
    console.log(cartProduct.mixMatch)
    product.map(function(p) {
        if (cartProduct.mixMatch) {
            p['mixMatch'] = true;
        }
        else {            
            p['mixMatch'] = false;
        }
        return p;
    })  
})

You need not use another else if block to check & set false. I also recommend you check if you get mixMatch as true/false by printing it in console.

  • Related