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 ?
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.
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.
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.
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.
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
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