Reputation: 672
I added autocomplete field on my form in order to select a patient. The patient data come from database. The problem is there are 40.000 patients
So i would like to load data after user has entered 3 characters minimum. But i don't know how to check that and how to pass the input to the function (filter argument). This is what i have done. for the moment the data are loaded when i click on the input field :
HTML :
<mat-form-field class="index-full-width">
<input
matInput
type="text"
[(ngModel)]="patientChoice"
placeholder="Patient"
aria-label="Patient"
[matAutocomplete]="autoPatient"
[formControl]="myControl"
(click)="getPatients()">
<mat-autocomplete (optionSelected)="selectPat()" #autoPatient="matAutocomplete" [displayWith]="displayFnPat">
<mat-option *ngFor="let patient of filteredPatients | async" [value]="patient">
<span>{{ patient.lastName }}</span>
<small>{{patient.firstName}}</small> |
<span>né(e) le {{ patient.dateNaissance }}</span> |
<small>IPP: {{patient.ipp}}</small>
</mat-option>
</mat-autocomplete>
</mat-form-field>
TS :
getPatients() {
let searchTerm = '*';
let success: any = {};
this.klinckServices.getPatients(searchTerm)
.then((webScriptdata) => {
success = webScriptdata;
this.listPatients = success.data.items ;
console.log(this.listPatients);
},
msg => {
alert(msg);
});
}
ngOnInit() {
this.filteredPatients = this.myControl.valueChanges.pipe(
startWith<string | Patient>(''),
map(patient => typeof patient === 'string' ? patient : patient.name),
map(name => name ? this.filterPatient(name) : this.listPatients.slice())
);
}
displayFnPat(patient: Patient): string | undefined {
return patient ? patient.name : undefined;
}
filterPatient(name: string) {
return this.listPatients.filter(patient =>
patient.name.toLowerCase().includes(name.toLowerCase()));
}
Upvotes: 1
Views: 7866
Reputation: 672
OK, solved by adding in HTML (keyup)="getPatients($event)" :
<input
matInput
type="text"
[(ngModel)]="patientChoice"
placeholder="Patient"
aria-label="Patient"
[matAutocomplete]="autoPatient"
[formControl]="myControl"
(keyup)="getPatients($event)"
>
And in TS file :
getPatients(event: any) {
let searchTerm = '';
searchTerm += event.target.value;
console.log(searchTerm);
if (searchTerm.length === 2) {
let success: any = {};
this.klinckServices.getPatients(searchTerm)
.then((webScriptdata) => {
success = webScriptdata;
this.listPatients = success.data.items;
console.log(this.listPatients);
},
msg => {
alert(msg);
});
}
}
Upvotes: 1
Reputation: 183
There's another way to do it and it is recommended here.
It's basically checking the length on your filter
method.
filterPatient(name: string) {
if (name.length < 2) {
return [];
}
return this.listPatients.filter(patient =>
patient.name.toLowerCase().includes(name.toLowerCase()));
}
Upvotes: 3