Matt
Matt

Reputation: 3706

Angular 5 material, fetch mat-options (in autocomplete/select list) from backend server

I'm upgrading an app from AngularJS to Angular 5. I figured most things out, but still in a bit of a learning process, and I can't figure out the best way to connect an autocomplete list to the backend. The Material Design website doesn't mention this either.

Here's what the code looks like now:

  <mat-form-field>

    // chips are up here

    <mat-autocomplete (optionSelected)="chipAdd($event,field)" #auto="matAutocomplete">
      <mat-option [value]="opt.id" *ngFor="let opt of field.options">
        {{ opt.name }}
      </mat-option>
    </mat-autocomplete>

  </mat-form-field>

I've removed the mat-chip-list and only included the relevant code.

So my question is... right now I'm getting the options from field.options -- instead of this, how can I load them dynamically from the http backend, once I start typing?

Thanks for your help! :)

Upvotes: 0

Views: 5048

Answers (1)

Radosław Roszkowiak
Radosław Roszkowiak

Reputation: 6871

You can use reactive forms to achieve that. The docs here: https://angular.io/guide/reactive-forms.

Form's value changes can be a stream. You can query the back-end based on the input value.

I.e. (in the component ts file):

// define appropriate type for your options, string[] just as an example,
// I don't know what you'll receive from the back-end and use as the option:
public autocompleteOptions$: Observable<string[]>;

constructor(private http: HttpClient) { }

ngOnInit() {
  // If you don't know how to have reactive form and subscribe to value changes,
  // please consult: https://angular.io/guide/reactive-forms#observe-control-changes

  this.autocompleteOptions$ = this.inputFormControl.valueChanges
    // this inputFormControl stands for the autocomplete trigger input   
    .debounceTime(150)
    // well, you probably want some debounce
    .switchMap((searchPhrase: string) => {
    // "replace" input stream into http stream (switchMap) that you'll subscribe in the template with "async" pipe,
    // it will run http request on input value changes
       return this.http.get('/api/yourAutocompleteEndpoint', { search: { 
          value: searchPhrase }}
       });
   }
 }

Then, in your component's template:

<mat-option [value]="opt.id" *ngFor="let opt of autocompleteOptions$ | async">
  {{ opt.name }}
</mat-option>

There might be some additional features required, like filtering in this stream not to trigger autocomplete when the number of chars is too low or something, but this is just the base example you can potentially follow.

Upvotes: 5

Related Questions