Home > Enterprise >  How to run the combinelatest on button trigger
How to run the combinelatest on button trigger

Time:09-30

 this.filteredProduct$ = combineLatest([
      this.productDataList$,
      this.productFilterApplied$,
      this.collectionFilterApplied$,
      this.statusFilterApplied$,
      this.unitPriceFilterApplied$,
      this.markUpFilterApplied$
    ]).pipe(
      map(([products, producttype, collection, status, unitPrice, markup]: any) => {
        if (producttype && producttype.length) {
          products = products.filter((product: any) => producttype.includes(product.productType));
        }

        if (collection && collection.length) {
          products = products.filter((product: any) => collection.includes(product.collections));
        }

        if (status && status.length) {
          products = products.filter((product: any) => status.includes(product.downstreamStatus));
        }

        if (unitPrice && unitPrice.length) {
          console.log(unitPrice);
          if (unitPrice == "0-100") {
            products = products.filter((item: any) => Math.round(item?.unitPriceWithShippingFee) >= 0 && Math.round(item?.unitPriceWithShippingFee) <= 100)
          } else if (unitPrice == "100-500") {
            products = products.filter((item: any) => Math.round(item?.unitPriceWithShippingFee) >= 100 && Math.round(item?.unitPriceWithShippingFee) <= 500)
          } else if (unitPrice == "500-1000") {
            products = products.filter((item: any) => Math.round(item?.unitPriceWithShippingFee) >= 500 && Math.round(item?.unitPriceWithShippingFee) <= 1000)
          } else if (unitPrice == "1000 and above") {
            products = products.filter((item: any) => Math.round(item?.unitPriceWithShippingFee) >= 1000)
          } else if (unitPrice == 'clear') {
            products = products;
          }
        }

        if (markup && markup.length) {
          console.log(markup);
          if (markup == "0-25 (%)") {
            products = products.filter((item: any) => Math.round(item?.markup) >= 0 && Math.round(item?.markup) <= 25)
          } else if (markup == "25-50 (%)") {
            products = products.filter((item: any) => Math.round(item?.markup) >= 25 && Math.round(item?.markup) <= 50)
          } else if (markup == "50-75 (%)") {
            products = products.filter((item: any) => Math.round(item?.markup) >= 50 && Math.round(item?.markup) <= 75)
          } else if (markup == "75-100 (%)") {
            products = products.filter((item: any) => Math.round(item?.markup) >= 75 && Math.round(item?.markup) <= 100)
          } else if (markup == 'clear') {
            products = products;
          }
        }

        return products;
      })
    );

I am having this combinelatest for mulitiple filtering through checkbox, if the value is checked, the filterValue is passed to productfilterapplied$.next and the combinelatest is working right

public productChanged(filterValue: any) {
      if (filterValue.name != undefined) {
        console.log('produtype  type', this.productFilterApplied$);
        const currentFilters = this.productFilterApplied$.getValue();
        const idx = currentFilters.indexOf(filterValue.name);
        if (idx >= 0) {
          currentFilters.splice(idx, 1)
        } else {
          currentFilters.push(filterValue.name)
        }

        this.productFilterApplied$.next(currentFilters)
        console.log('produtype  type', this.productFilterApplied$);
      }

Now I am having a apply button, i want to check the checkbox and by clicking the apply button only i want to run the combinelatest.

CodePudding user response:

one of the possible solution

import { Component } from "@angular/core";

import { mergeMap, exhaustMap } from "rxjs/operators";
import { HttpClient } from "@angular/common/http";
import { BehaviorSubject } from "rxjs";

@Component({
  selector: "my-app",
  template: `
    <button (click)="onSubmit()">submit</button>
  `,
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  submit$ = new BehaviorSubject(null);
  constructor(private http: HttpClient) {}
  ngOnInit() {
    combineLatest([ // COMBINELATEST LOGIC HERE
this.submit$.pipe(filter(i => i)), // filter falsy values
....
])

  }
  onSubmit() {
    this.submit$.next(true);
  }
}

CodePudding user response:

Assuming you want to delay combineLatest Observable to trigger until the apply button is clicked

// create apply button in template

<button #btn>Apply</button>

// create elementRef in component

@ViewChild('btn', { static: true }) button: ElementRef;

// create Observable out of it

  const applyBtn$ =  fromEvent(this.button.nativeElement, 'click');

// Wrap combineLatest inside a method and return it instead of assigning to this.filteredProduct$ like

funWithCombineLatest(): Observable<any>{
    return combineLatest([
      ...other obervable
    ]);
}

Use switchMap with applyBtn$ and assign the result to this.filteredProduct$

this.filteredProduct$ = applyBtn$.pipe(
    switchMap(_ => functionWithCombineLatest()),
);

Since now combine latest is dependent on apply button click, it will never trigger until an apply button is clicked.

  • Related