Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get 'id' selected value from autocomplete in angular material

Tags:

angular

How can I set mat-autocomplete in order to get the selected option ID?

<mat-form-field>
    <input type="text" matInput 
        [formControl]="autocompleteControl" 
        [matAutocomplete]="auto">
        <mat-autocomplete #auto="matAutocomplete">
            <mat-option *ngFor="let book of books" [value]="book.id"> <!-- THIS SHOW THE ID ON THE UI -->
                {{ book.title }}
            </mat-option>
        </mat-autocomplete>
</mat-form-field>

If I change "book.title" for "book.id" at [value] attribute, the UI shows the ID on the autocomplete input, which is not good. Where should I put the "book.id" in order to ask for him later on my component.ts?

like image 546
napstercake Avatar asked Dec 23 '19 04:12

napstercake


2 Answers

You could use displayWith to display a specific value for an option.

It takes a mapping function that would get the value of the mat-option and return the display value for the mat-option

Give this a try:

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

/**
 * @title Simple autocomplete
 */
@Component({
  selector: 'autocomplete-simple-example',
  templateUrl: 'autocomplete-simple-example.html',
  styleUrls: ['autocomplete-simple-example.css'],
})
export class AutocompleteSimpleExample {
  myControl = new FormControl('1');
  options: string[] = ['One', 'Two', 'Three'];
  books: Array<{ id: string; title: string }> = [
    { id: '1', title: 'Book 1' },
    { id: '2', title: 'Book 2' },
    { id: '3', title: 'Book 3' },
    { id: '4', title: 'Book 4' },
  ];

  getTitle(bookId: string) {
    return this.books.find(book => book.id === bookId).title;
  }

  onSubmit() {
    console.log(this.myControl.value);
  }
}

And in the template:

<form class="example-form">
  <mat-form-field class="example-full-width">
    <input 
      type="text" 
      placeholder="Pick one" 
      aria-label="Number" 
      matInput 
      [formControl]="myControl" 
      [matAutocomplete]="auto">
    <mat-autocomplete 
      #auto="matAutocomplete"
      [displayWith]="getTitle.bind(this)">
      <mat-option 
        *ngFor="let book of books" 
        [value]="book.id">
        {{book.title}}
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>
  <button (click)="onSubmit()">Submit</button>
</form>

Here's a Working Sample Demo Code your ref.

like image 70
SiddAjmera Avatar answered Sep 18 '22 00:09

SiddAjmera


This is a simpler way to implement it. Taken from Github. All credits belong to nayfin.

On HTML:

options: User[] = [
 {name: 'Mary', id: 1},
  {name: 'Shelley', id: 2},
  {name: 'Igor', id: 3}
];
// we expect the options to be passed in from the template
// then we return a callback function that will expect an id which is passed in by the autocomplete event logic
displayFn(options: User[]): (id: number) => string {
  return (id: number) => { 
    const correspondingOption = Array.isArray(options) ? options.find(option => option.id === id) : null;
    return correspondingOption ? correspondingOption.name : '';
  }
}

and on .ts

<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn(options)">
  <mat-option *ngFor="let option of filteredOptions | async" [value]="option.id">
    {{option.name}}
  </mat-option>
</mat-autocomplete>
like image 37
Cafn Avatar answered Sep 22 '22 00:09

Cafn