I am making a zoo angular project practicing RXJS, where when the user searches or puts in a keystroke it first waits a couple milliseconds before searching so you dont do it on every key stroke.
Then will filter the list already received from a fetch.
However I notice that it seems to be on key behind.
Meaning: For example a smal list of animals like { Leo, Lane, John }
I type in L in the search bar all three still show, I then type in La (expecting just lane) then Leo and Lane show up (so what it should have done when I typed in just L)
Then I do Lan and then just Lane shows up.
I am trying to have the search bar update with each keystroke not one keystroke behind.
HTML:
@for (animal of userAnimals; track animal) {
{{ animal.name }} The {{ animal.species }}
@if (animal.openStatus) {
{{ animal.name }} Is open
} @else {
{{ animal.name }} Is Closed
}
grid-view.ts:
searchSubjet$ = new Subject();
public animals: IAnimal[] = [];
public userAnimals: IAnimal[] = [];
public searchString!: string;
// Inject the list of animals
constructor(
private animalListService: Animalslist,
private notifyService: NotificationService,
private cdr: ChangeDetectorRef,
) {
afterNextRender(() => {
this.notifyService.enableNotifications();
});
}
public async ngAfterViewInit(): Promise {
this.searchSubjet$.pipe(debounceTime(500)).subscribe((userSearch) => {
console.log(userSearch);
if (userSearch === '' || userSearch === null) {
this.userAnimals = this.animals;
} else {
this.userAnimals = this.animals.filter((a) =>
a.name.toUpperCase().startsWith(userSearch.toUpperCase()),
);
}
this.cdr.detectChanges();
});
}
public async ngOnInit() {
// Get the list of animals.
// This list can be iterated over to make a proper grid view of animals.
this.animals = await this.animalListService.getAll();
this.userAnimals = this.animals;
// https://stackoverflow.com/questions/34364880/expression-has-changed-after-it-was-checked
// this.cdr.detectChanges();
}
public inputChanged($event: any) {
this.searchSubjet$.next($event.srcElement.value);
}