I have a list of about 4k items that I want the autocomplete input to search trough. Because it's really not that practical to fetch them in the constructor and filter them (as a few answers here suggest) in the angular app, I want to make the search on the server and return the data to the component.
I'm a bit lost on how the code should look like, but here's my attempt:
HTML
<mat-form-field class="w-100">
<input #searchInput [matAutocomplete]="searchOptions" formControlName="search" matInput placeholder="Search"/>
</mat-form-field>
<mat-autocomplete #searchOptions="matAutocomplete">
<mat-option *ngFor="let item of items | async" [value]="item.id">
{{ item.description }}
</mat-option>
</mat-autocomplete>
Typescript
export class SearchDialogComponent {
myForm: FormGroup;
items: any;
constructor(public formBuilder: FormBuilder,
public itemService: ItemService,
public dialogRef: MatDialogRef<SearchDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: any) {
this.createForm();
}
ngOnInit(): void {
this.items = this.myForm.get('search').valueChanges.map(q => this.searchFilter(q));
}
createForm() {
this.myForm = this.formBuilder.group({
search: new FormControl(''),
});
}
searchFilter(q: string) {
this.itemService.fullSearch(q).subscribe(result => {
return result; // This won't work, but I have no idea what will :)
});
}
}
Oh! Then two things:
flatMap() operator and perform the search service call;async pipe.I assume that itemService.fullSearch() returns Observable<T[]> where T is result type.
P.S. This issue would take way less time if any was not in original code; and the signature of searchFilter method declared a return type. TypeScript is all about making JavaScript at least a bit type safer.
this.items = this.myForm
.get('search')
.valueChanges
.flatMap(searchQuery => this.itemService.fullSearch(searchQuery));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With