So I have a list of 2000+ employees and I need to filter through them. As I currently have it, it goes super slow and lags for 2 seconds. Everytime I type in a letter, it passes that list each time.
Any way to midigate the lag?
Update
This is some sample code:
<div style="margin-bottom:30px;" *ngIf="emulatedList">
<input type="text" style="width:200px; background-color:#eeeeee;" name="searchText" [(ngModel)]="searchText" placeholder="Filter Dropdown List">
<select style="background-color:#eeeeee;" [(ngModel)]="selected" placeholder="Emulate Person">
<option *ngFor="let delegate of emulatedList | filter: searchText; trackBy: trackByName" [ngValue]="delegate.employeeid">
{{delegate.employeename}}
</option>
</select>
<span>
<a (click)="addDelegate(selected)" style="background-color:#5B9C64; font-size:16px; color:#ffffff; padding:10px; margin-right:30px; border-radius: 10px;">Add Delegate</a>
</span>
</div>
The component.ts file:
ngOnInit() {
this.personsService.getEmulateList().subscribe(data => {
setTimeout( () => {
//console.log(data);
this.emulatedList = data;
}, 300);
});
You can use a timeout, so that the code is not run until there have been no requests for x seconds
In the example below, although doFiltering is called in a loop 10 times, the console log statement is only printed once, exactly 1 second after the loop has finished
let handle;
for(var i = 0; i < 10; i++) {
doFiltering();
}
function doFiltering() {
// Check if there is a reference to running timeout
if (handle != null) {
// Cancel it
clearTimeout(handle);
}
// Start a timeout
handle = setTimeout(() => {
// Do you filtering in here
console.log("Filtering now");
handle = null;
}, 1000);
}
Rather than using pipe use rxjs/add/operator/debounceTime
as:
HTML
<input [ngModel]='filterValue' (ngModelChange)='changed($event)' />
component.ts
filterValue: string;
modelChanged: Subject<string> = new Subject<string>();
constructor() {
this.modelChanged
.debounceTime(500) // you can change time
.distinctUntilChanged() // emit only when value is different from previous value
.subscribe(value => {
this.filterValue = value;
// perform filter
});
}
changed(text: string) {
this.modelChanged.next(text);
}
You can use debounceTime
if you are listening to the changing value. Not sure if you are using [(ngModel)]
or a reactive form. It should be something like:
this.formCtrlSub = this.firstNameControl.valueChanges
.debounceTime(1000)
.subscribe(newValue => this.fetchNewResults());
Instead of using the pipe, you can use a timer to wait for the user to stop typing and then filtering the results.
timer: any;
getList(searchText) {
if (searchText.length >= 3) {
clearTimeout(this.timer);
this.timer = setTimeout(() => {
// filter here
}, 1100);
}
else {
this.list= [];
}
}