Angular 5 / Material 2 - Wrong value in field after option is selected
You can use displayWith
function.
Your component.html would become
<div class="form-group"> <mat-form-field class="example-full-width"> <input type="text" placeholder="Firmware auswählen" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto1"> <mat-autocomplete #auto1="matAutocomplete" [displayWith]="displayFn"> <mat-option *ngFor="let firmware of filteredFirmware | async" [value]="firmware" (onSelectionChange)="getXXX(firmware)> {{ firmware.name }} </mat-option> </mat-autocomplete> </mat-form-field></div>
Then define following display function in you component.ts
displayFn(firmware: any): string { return firmware? firmware.name : firmware;}
You can access firmware id in getXXX(firmware)
function which you define in your component.ts. This function will be called on selection change.
getXXX(firmware) { this.selectedFirmware = firmware; // here you can get id // firmware._id}
and filter function
filterFirmware(val: any): any[] { let name = val.name ? val.name : val; return this.availableFirmware.filter(firmware => { return firmware.name.toLowerCase().indexOf(name.toLowerCase()) > -1; }); }
You can use the displayWith attribute like:
In your component:
import { Component, OnInit, OnDestroy } from '@angular/core';import { FormControl } from '@angular/forms';import { Observable } from 'rxjs/Observable';import { Subscription } from 'rxjs/Subscription';import { map } from 'rxjs/operators/map';import {startWith} from 'rxjs/operators/startWith';@Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: [ './app.component.css' ]})export class AppComponent implements OnInit, OnDestroy { myControl = new FormControl(); availableFirmware = [{name: 'Firmware 1', id: 1}, {name: 'Firmware 2', id: 2}, {name: 'Firmware 3', id: 3}]; selected = null; filteredFirmware: Observable<any>; subcribtion: Subscription; displayFirmware(firmware?: any) { return firmware ? firmware.name : undefined; } filterFirmware(val: any): any[] { return this.availableFirmware.filter(firmware => { // when no selection occured value is a string // but once a firmware is selected value is an object let name = val.name ? val.name : val; return firmware.name.toLowerCase().indexOf(name.toLowerCase()) === 0; }); } ngOnInit() { this.subcribtion = this.myControl.valueChanges.subscribe(value => this.selected = value); this.filteredFirmware = this.myControl.valueChanges.pipe( startWith(''), map(val => this.filterFirmware(val)) ); } ngOnDestroy() { this.subcribtion.unsubscribe(); }}
In the template:
<div class="form-group"> <mat-form-field class="example-full-width"> <input type="text" placeholder="Firmware auswählen" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto1"> <mat-autocomplete #auto1="matAutocomplete" [displayWith]="displayFirmware"> <mat-option *ngFor="let firmware of filteredFirmware | async" [value]="firmware"> {{ firmware.name }} </mat-option> </mat-autocomplete> </mat-form-field></div><p> {{selected | json}}</p>
In this solution the value is the whole firmware object so you can retrieve anything from it.
You can find a running example here https://stackblitz.com/edit/angular-ptg4i1