Search code examples
angularprimeng

How to refresh a list in Angular based on user input


Basically I'm trying to create a simple search bar with static data. I tried multiple approaches. I'm using primeng's ListBox to display the list of searched items. Here are some bits and pieces of my code:

HTML:

<input
  type="text"
  placeholder="Search..."
  [(ngModel)]="searchValue"
  (keyup)="refreshSearchList(searchValue)"
  #myInput
/>

<p-listbox
  [options]="searchList"
  [(ngModel)]="selectedFruit"
  optionLabel="name"
></p-listbox>

TS

  interface Fruit {
    name: string;
    code: number;
  }

  searchList: Fruit[] = [
    { name: 'Apple', code: 1 },
    { name: 'Banana', code: 2 },
    { name: 'Guavava', code: 3 },
    { name: 'Kiwi', code: 4 },
    { name: 'Blueberry', code: 5 },
    { name: 'Pine Apple', code: 6 },
    { name: 'Strawberry', code: 7 },
  ];

  sendEntireList(): Fruit[] {
    return this.searchList;
  }

my main logic to filter out by term is this:

  filterByKey(searchWhat: string) {
    let wholeList = this.sendEntireList();
    wholeList.map((item: any) => {
      if (item.name.includes(searchWhat)) {
        this.list.push(item);
      }
    });
    return this.list;
  }

I also tried to achieve this using RxJs:

  @ViewChild('myInput') myInput: ElementRef;

  ngAfterViewInit() {
    let term = fromEvent(this.myInput.nativeElement, 'keyup');
    term
      .pipe(debounceTime(1000), distinctUntilChanged())
      .subscribe((res: any) => {
        // console.log(res);
        // call refreshSearchList here
      });
  }

Somewhere i'm missing something important. My code is not working at all. Here is the complete Stackblitz. Please point out my mistake.


Solution

  • You can just use ngModelChange output like below

    <input type="text" placeholder="Search..."
      [(ngModel)]="searchValue" (ngModelChange)="onQueryChange()"
    />
    
    <p-listbox [options]="filteredList" optionLabel="name"></p-listbox>
    

    And in your TypeScript file

    import { Component } from '@angular/core';
    
    interface Fruit {
      name: string;
      code: number;
    }
    
    @Component({
      selector: 'app-search-box',
      templateUrl: './search-box.component.html',
      styleUrls: ['./search-box.component.css'],
    })
    export class SearchBoxComponent {
      searchList: Fruit[] = [
        { name: 'Apple', code: 1 },
        { name: 'Banana', code: 2 },
        { name: 'Guavava', code: 3 },
        { name: 'Kiwi', code: 4 },
        { name: 'Blueberry', code: 5 },
        { name: 'Pine Apple', code: 6 },
        { name: 'Strawberry', code: 7 },
      ];
    
      filteredList = this.searchList;
    
      searchValue = '';
    
      onQueryChange() {
        this.filteredList = this.searchList.filter((item) =>
          item.name.toLowerCase().includes(this.searchValue.toLowerCase())
        );
      }
    }
    
    

    StackBlitz working version

    https://stackblitz.com/edit/primeng-calendar-demo-jd25su