Reputation: 41
How to use debounce time in an angular input search while searching through the list of items.Should i use RXJS and how to put it in my function filterReports? Can you please show me in code what i should do? Code here:
protected reports: Array<ReportGroupModel> = [];
protected filteredReports: Array<ReportGroupModel> = [];
constructor(
protected route: ActivatedRoute,
protected httpService: HttpService
) {
super(route);
this.titleIcon = 'fa-bar-chart';
this.titleSufixKey = 'reports';
this.filterReports = debounce(this.filterReports, 500);
}
filterReports(filter: any) {
const searchText = filter.target.value?.toUpperCase();
if (searchText) {
let newFilteredReports: Array<ReportGroupModel> = [];
for (let reportGroup of this.reports) {
let foundItems = reportGroup.items.filter(x => x.title.toUpperCase().includes(searchText));
if (foundItems && foundItems.length > 0) {
newFilteredReports.push(new ReportGroupModel(reportGroup.header, foundItems));
}
}
this.filteredReports = newFilteredReports;
}
else
this.filteredReports = this.reports;
}
ngOnInit() {
super.ngOnInit();
this.filteredReports = this.reports;
}
and here is html
<div class="d-flex">
<input search="text" class="form-control mw-200p ml-auto" (keyup)="component.filterReports($event)" autofocus placeholder="{{ 'search' | translate }}"/>
</div>
<div class="d-flex flex-wrap pl-2">
<div *ngFor="let report of component?.filteredReports" class="pr-5 pt-2" style="width: 350px;">
<h3>{{report.header | translate}}</h3>
<ul class="list-unstyled pl-1">
<li *ngFor="let item of report.items">
<i class="fa {{item.icon}} mr-h"></i>
<a class="link" [routerLink]="item.path"> {{item.title}} </a>
<p *ngIf="item.description" class="text-muted">{{item.description}}</p>
</li>
</ul>
</div>
</div>
Upvotes: 0
Views: 1180
Reputation: 161
The easiest way to solve this issue is to use the reactive form module. however, if you want to stick with ngModel, you can do something like this.
searchChanged = new Subject();
protected reports: Array<ReportGroupModel> = [];
protected filteredReports: Array<ReportGroupModel> = [];
and update the subject every time the keyup event update
<div class="d-flex">
<input search="text" class="form-control mw-200p ml-auto" (keyup)="onKeyUp($event)" autofocus placeholder="{{ 'search' | translate }}"/>
</div>
//.ts
onKeyUp(value: string) {
this.searchChanged.next(value)
}
Now, you can use searchChanged subject to debounce the event update
constructor(
protected route: ActivatedRoute,
protected httpService: HttpService
) {
...
this.searchChanged.pipe(
debounceTime(300)
// You better add takeUntil or something to unsubscribe this observable when this component destroy
).subscribe(value => {
this.filterReports(value);
})
}
Upvotes: 2