shafeequemat
shafeequemat

Reputation: 1052

How to implement Angular Material 2 Autocomplete with AJAX

I am using Angular Material 2 Autocomplete in my Angular 4 project. How can I implement such that the autocomplete values are loading from an HTTP call, in this example?

Can anyone give me a Plunker demo? Thank you

Upvotes: 2

Views: 5661

Answers (1)

AVJT82
AVJT82

Reputation: 73357

First of all, you should please show some attempt to solve your issue, but luckily I'm bored and will provide an answer ;)

Here in this sample I'm using: https://jsonplaceholder.typicode.com/users

we store that JSON result as an observable in users. Then we have our observable filteredUsers which will be shown in template. Since this is a http-request, we would want to use distinctUntilChanged and debounceTime of your choosing, to restrict the http-requests. The formcontrol we are using to capture the value user is typing is in this example searchCtrl. When listening to valueChanges, we use switchMap to flatten the result.

So based on the above comments, your code would look like the following:

UPDATE (rxjs 6)

this.filteredUsers = this.searchCtrl.valueChanges.pipe(
  startWith(null),
  debounceTime(200),
  distinctUntilChanged(),
  switchMap(val => {
    return this.filter(val || '')
  })
 )
}

filter(val: string) {
  return this.users.pipe(
    map(response => response.filter(option => {
      return option.name.toLowerCase().indexOf(val.toLowerCase()) === 0
    }))
  )
}

and for the template, we use the async pipe:

<mat-form-field>
  <input matInput [matAutocomplete]="auto" [formControl]="searchCtrl">
  <mat-autocomplete #auto="matAutocomplete">
    <mat-option *ngFor="let user of filteredUsers | async" 
      [value]="user.name">
      <span>{{ user.name }}</span>
    </mat-option>
  </mat-autocomplete>
</mat-form-field>

DEMO


OLD:

this.filteredUsers = this.searchCtrl.valueChanges
  .startWith(null)
  .debounceTime(200)
  .distinctUntilChanged()
  .switchMap(val => {
    return this.filter(val || '')
})      

filter(val: string) {
  return this.users
    .map(response => response.filter(option => { 
      return option.name.toLowerCase().indexOf(val.toLowerCase()) === 0
    }));
}

DEMO

Upvotes: 6

Related Questions