Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remote search using Angular Material 2

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 :) 
        });
    }
}
like image 719
GregoryHouseMD Avatar asked Jan 24 '26 08:01

GregoryHouseMD


1 Answers

Oh! Then two things:

  • Use flatMap() operator and perform the search service call;
  • Do NOT subscribe to that observable, since you're using 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));
like image 85
Igor Soloydenko Avatar answered Jan 25 '26 21:01

Igor Soloydenko