I am using ng-select with type-ahead filtering of items in the select list. When you type to filter the results for the first item in the list, the performance is lightning fast. After you select that first item, however, everything becomes extremely slow. I don't know rxjs well enough to understand what the bottleneck is.
My template:
<label>Select Employees:</label>
<ng-select [items]="people$ | async"
bindLabel="full_name"
[multiple]="true"
[addTag]="addCustomItem"
[hideSelected]="true"
[trackByFn]="trackByFn"
[minTermLength]="2"
[loading]="peopleLoading"
typeToSearchText="Please enter 2 or more characters (of first OR last name)"
[typeahead]="peopleInput$"
[(ngModel)]="selectedPersons">
</ng-select>
<br>
<div style="margin-bottom:100px">Selected persons: {{selectedPersons | json}}</div>
My Typescript component:
import { Component, OnInit } from '@angular/core';
import { concat, Observable, of, Subject } from 'rxjs';
import { Person, Employee } from './data.service';
import { catchError, distinctUntilChanged, switchMap, tap } from 'rxjs/operators';
import { NodeHTTPService } from '../../node-http.service';
@Component({
selector: 'app-employee-picker',
templateUrl: './employee-picker.component.html',
styleUrls: ['./employee-picker.component.css']
})
export class EmployeePickerComponent implements OnInit {
people$: any/*Observable<Employee[]>*/; // you can see I had an issue here.
peopleLoading = false;
peopleInput$ = new Subject<string>();
selectedPersons: Employee[];
addCustomItem: boolean = false; // setting this to true allows users to add custom items not in the select list.
constructor(private _nodeHTTPService: NodeHTTPService) {
}
ngOnInit() {
this.loadPeople();
}
trackByFn(item: Person) {
return item.id;
}
private loadPeople() {
this.people$ = concat(
of([]), // default items
this.peopleInput$.pipe(
distinctUntilChanged(),
tap(() => this.peopleLoading = true),
switchMap(term => this._nodeHTTPService.getUsers(term).pipe(
catchError(() => of([])), // empty list on error
tap(() => this.peopleLoading = false)
))
)
);
console.log('this.people$: ', this.people$)
}
}
The NodeHttpService:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { CdfServiceService } from "./cdf-service.service";
@Injectable({
providedIn: 'root'
})
export class NodeHTTPService {
constructor(private http: HttpClient, private _cdfServiceService: CdfServiceService) { }
getUsers(i) {
if (!i) { i = ''};
let users = this.http.get(`https://chq-smscqa01.chq.ei/db/users?user=${i}`)
return users;
}
}
I really appreciate any input on this question! Thank you.