Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MatAutocomplete with observables

I'm using Material Autocomplete component.

First letter I type into the input, it works as expected, but it fails next.

That's obviously because I set a new value for this.filteredUnitName:

export class ActionDetailComponent {
    @Input() unitNames: Observable<string[]>;

    filteredUnitNames: Observable<string[]>;

    unitName: FormControl = new FormControl();

    ngOnInit() {
        this.filteredUnitNames = this.unitName.valueChanges
            .startWith(null)
            .do(val => {
                if (val) {
                    this.filteredUnitNames = this.filter(val); // bad line
                }
            });
    }

    filter(val: string): Observable<string[]> {
        return this.unitNames
            .map(response => response.filter(
                option => option.toLowerCase().indexOf(val.toLowerCase()) === 0
            ));
    }

Here is my template :

<mat-form-field>
    <input matInput placeholder="Unit name" class="form-control" [formControl]="unitName" [matAutocomplete]="auto">
    <mat-autocomplete #auto="matAutocomplete">
    <mat-option *ngFor="let name of filteredUnitNames | async" [value]="name">
        <span>{{name}}</span>
    </mat-option>
    </mat-autocomplete>
</mat-form-field>

Is there another way to make this working properly ?

like image 507
Menencia Avatar asked Oct 28 '17 13:10

Menencia


People also ask

How do you use a matAutocomplete?

Simple autocomplete Each option should be defined by a mat-option tag. Set each option's value property to whatever you'd like the value of the text input to be when that option is selected. Next, create the input and set the matAutocomplete input to refer to the template reference we assigned to the autocomplete.

What is matAutocomplete?

The <mat-autocomplete>, an Angular Directive, is used as a special input control with an inbuilt dropdown to show all possible matches to a custom query. This control acts as a real-time suggestion box as soon as the user types in the input area.

Can't bind to matAutocomplete since it isn't a known property of input angular?

If 'mat-option' is an Angular component and it has 'value' input, then verify that it is part of this module. If 'mat-option' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule. schemas' of this component to suppress this message.

How do you clear mat autocomplete when no option is selected from autocomplete dropdown?

You can remove the formControl-binding from your input and when you select an option you set that id to your form. You are already calling such a function (onSelectionChange)="onEnteredAccount(accountOption)" in which you can do that.


1 Answers

You can achieve this with the switchMap operator, so change your code to the following:

import "rxjs/add/operator/switchMap";


ngOnInit() {
  this.filteredUnitNames = this.unitName.valueChanges
    .startWith(null)
    .switchMap(val => {
      return this.filter(val || '')
   })
}

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

DEMO: https://plnkr.co/edit/yb4NeYTbGkwHay15R8CW?p=preview

like image 121
AT82 Avatar answered Sep 20 '22 17:09

AT82