filter not trigger the change event from text input

45 Views Asked by At

I would like to understand, why the change deduction is not works, on keyup while integrate the filter using the input value.

when the key ups, I am getting no of empty string popups to prevent the filter.

here is the code:

import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule],
  template: `
    <p>register works!</p>
  <input aria-label="filter text" (keyup)="filterIt($event)" type="text" />
  <div *ngFor="let student of filterStudent(); trackBy:identify">{{student}}</div>
  `,
})
export class App {
  students = ['Yamini', 'Surat', 'Arif', 'Madura'];

  filterStudent(str = '') {
    console.log(str)
    const filtered = this.students.filter((student) =>
      student.toLocaleLowerCase().includes(str.toLocaleLowerCase())
    );
    return filtered;
  }

  filterIt($event: Event) {
    const event = $event.target as HTMLInputElement;
    this.filterStudent(event.value);
  }

  identify(_index: number, name: string) {
    return name;
  }
}

bootstrapApplication(App);

Live Example

1

There are 1 best solutions below

2
yurzui On BEST ANSWER

You're always calling filterStudent() from template that always returns the same value.

Avoid calling methods withing template.

As an option you can create a property filteredStudents and update it on keyUp event:

ts

filteredStudents = this.students;
...
filterIt($event: Event) {
  const event = $event.target as HTMLInputElement;
  this.filteredStudents = this.filterStudent(event.value);
}

html

*ngFor="let student of filteredStudents; trackBy:identify">

Forked Stackblitz


Another option might be using Observable

html

*ngFor="let student of filteredStudents$ | async..."

ts

query$ = new BehaviorSubject('');

filteredStudents$ = this.query$.pipe(
  map(query => this.filterStudent(query))
);

filterIt($event: Event) {
  const event = $event.target as HTMLInputElement;
  this.query$.next(event.value);
}

Forked Stackblitz