angular-material2 – md-autocomplete – Separate control and display

This example shows how to to display specific property in dropdown but bind with the whole object.

autocomplete-overview-example.html:

<md-input-container>
  <input mdInput placeholder="State" [(ngModel)]="selection"
         [mdAutocomplete]="auto" [formControl]="stateCtrl">
</md-input-container>

<md-autocomplete #auto="mdAutocomplete" [displayWith]="displayFn">
  <md-option *ngFor="let state of filteredStates | async" [value]="state" >
    {{ state.Country }}
  </md-option>
</md-autocomplete>


<p>Selected Country: {{selection | json}}</p>
<p>Selected Country Id: {{selection?.CountryID}}</p>

autocomplete-overview-example.ts:

import {Component} from '@angular/core';
import {FormControl} from '@angular/forms';

import 'rxjs/add/operator/startWith';
import 'rxjs/add/operator/map';

@Component({
  selector: 'autocomplete-overview-example',
  templateUrl: 'autocomplete-overview-example.html',
})
export class AutocompleteOverviewExample {
  stateCtrl: FormControl;
  filteredStates: any;
  
  selection: any;

  states = [
    { Country: "United States Of America" , CountryID: "1"},
    { Country: "United Kingdom" , CountryID: "2"},
    { Country: "United Arab Emirates" , CountryID: "3"},
  ];

  constructor() {
    this.stateCtrl = new FormControl();
    this.filteredStates = this.stateCtrl.valueChanges
        .startWith(null)
        .map(country => country && typeof country === 'object' ? country.Country : country)
        .map(name => this.filterStates(name));
  }

  filterStates(val) {
    return val ? this.states.filter(s => s.Country.toLowerCase().indexOf(val.toLowerCase()) === 0)
               : this.states;
  }
  
  displayFn(country): string {
    console.log(country);
      return country ? country.Country : country;
   }

}

Live Example

if you want to reproduce, please indicate the source:
angular-material2 – md-autocomplete – Separate control and display - CodeDay