Search code examples
angularobservablerxjs-observables

How to filter observable data from api?


 public rows$: Observable<any[]>;
ngOnInit(): void {
    this.rows$ = this.StockService.findAll();
  }
  searchData(event: any) {
    let term: string = event.target.value;
    console.log(term);
     this.rows$.pipe(
      map((items) =>
        items.filter(
          (item) =>
            item.prdoct_code=== term ||
            item.product_name === term ||
        )
      )
    );
  }

I want to add a search for ngx datatable, this is how I code, but after searching, ngoninit works and instead of filtered data, all products come and none appear in the table?


Solution

  • Simply expressing this.rows$.pipe(...) does not affect the original observable, it defines a new one.

    In your case, you need to define rows$ to be an observable that depends on 2 different sources: the stock service results (items) and the search term (term). So, you need a way to have your search term be observable. We can use a -BehaviorSubject for this:

    private term$  = new BehaviorSubject<string>('');
    private items$ = this.StockService.findAll();
    
    public rows$: Observable<any[]> = combineLatest([this.items$, this.term$]).pipe(
      map(([items, term]) => items.filter(
         (item) =>
           term === '' ||
           item.prdoct_code === term ||
           item.product_name === term
      ))
    );
      
    searchData(event: any) {
      const term: string = event.target.value;
      this.term$.next(term);
    }
    

    The line private term$ = new BehaviorSubject<string>('') defines a subject that emits an initial value of empty string ''. We can push values through the subject by calling its .next() method and passing a value.

    We use combineLatest to define a single observable with multiple sources. combineLatest will emit the most recent value from each source whenever any of the sources emit a value. So, whenever your searchData() method is called, the most recen values of list and term will be emitted and pass through the filter logic in the .pipe(map(...)).