26

I have a form with various select boxes which use objects as the value:

<mat-option [value]="object">

Which works great when I am creating new records via the form. Now when I am editing records, I run into the problem that the object in the mat-select-option is not the "same" object that I get from my rest service, so my select boxes have no option selected when editing the record.

Is it possible to tell the select-box widget to match on object.id when deciding what option is selected? I think I may need to write a directive to handle this, but maybe this is already possible with Angular or Angular Material libraries, or another existing solution.

To elaborate I have my foo.component.ts file:

let item = {
    'fruit': { id: 1, 'label': 'Pineapple' },
}

let options = [
    { 'id':1, 'label': 'Pineapple' },
    { 'id':2, 'label': 'Banana' },
    { 'id':3, 'label': 'Papaya' }
]

And my .html file:

<mat-select  placeholder="Fruit" [(ngModel)]="item.fruit">
  <mat-option *ngFor="let option of options" [value]="option">{{option.label}}</mat-option>
</mat-select>

When the user visits the page, they should see "Pineapple" selected in the mat-select. Because the 'pineapple' in the item.fruit and the options array are not pointing to the same 'pineapple' object - the mat-select is empty.

I'd like to see something like:

<mat-select          
    placeholder="Fruit" 
    [(ngModel)]="item.fruit" 
    equalityAttr="id"
>
Maverik Minett
  • 2,131
  • 3
  • 17
  • 28
  • Maybe this can help you: https://stackoverflow.com/questions/35945001/binding-select-element-to-object-in-angular/35945293 – Aniket Kadam Aug 23 '18 at 15:48
  • 1
    Possible duplicate of [Binding select element to object in Angular](https://stackoverflow.com/questions/35945001/binding-select-element-to-object-in-angular) – ConnorsFan Aug 23 '18 at 15:50
  • This might help: https://stackoverflow.com/questions/35945001/binding-select-element-to-object-in- angular/35945293 – Aniket Kadam Aug 23 '18 at 15:51

1 Answers1

74

It is the [compareWith] directive. Angular.io is down at the moment, so I will ink to this medium article for reference.

HTML

<mat-select  
    placeholder="Fruit" 
    [(ngModel)]="item.fruit"
    [compareWith]="objectComparisonFunction">

   <mat-option *ngFor="let option of options" [value]="option">{{option.label}}</mat-option>
</mat-select>

TypeScript

  public objectComparisonFunction = function( option, value ) : boolean {
    return option.id === value.id;
  }
Maverik Minett
  • 2,131
  • 3
  • 17
  • 28
  • 2
    Updating in 2021, Was having the same issue, it worked with a little bit of changes ``` [(ngModel)] = "item.fruit" ``` to ``` [(value)] = "item" ``` everything else stays same. – Mani Oct 07 '21 at 18:50
  • 2
    Hm, I found that `value` might be undefined, so I used `return option.id === value?.id`. – Elias Jan 27 '22 at 14:55