Angular 2 Forms: binding html select to collection of objects

David Brem picture David Brem · Aug 22, 2016 · Viewed 10.7k times · Source

I would like to display a collection of selectable objects in an angular 2 application (RC 5, forms 0.3.0)

<select [(ngModel)]="selectedItem">       
  <option *ngFor="let item of selectableItems"
          [value]="item">
    {{ item }}
  </option>
</select>

<div> {{ selectedItem }} </div>

The list itself is correctly displayed.

But all that is displayed for 'selectedItem' is [object Object]. When accessing the item in code, I get the corresponding string "[object Object]". I tried switching to ngValue but that produces the same results.

The whole thing works when I use primitive values instead of objects. But I suspect that I am missing some crucial point here.

Thanks for your help. I've been wasting several hours on Internet search and trial and error. Maybe somebody has encountered the same problem.

Edit (24-08-16): I came across this tutorial which explains how to create common forms widgets today. Maybe it's useful for somebody who lands on this page: https://scotch.io/tutorials/how-to-deal-with-different-form-controls-in-angular-2

Answer

Ben Richards picture Ben Richards · Aug 22, 2016

From your code and explanation, I assume "item" is a complex object, and not a simple object. So to display it in HTML you would use:

<div> {{ selectedItem | json }} </div>

In code you have to access the "item" properties (as in item.value or whatever the item's properties are. If you want to work with simple values you can do something like this:

<select [(ngModel)]="selectedItem">       
  <option *ngFor="let item of selectableItems"
          [value]="item.id">
    {{ item }}
  </option>
</select>

This is of course assuming item is a complex type.

Edit

After some digging (because this has plagued me as well), I found the solution I really wanted! To use complex object you just need to use [ngValue] when binding the value! The fix is described at https://github.com/angular/angular/issues/4843. So the above will look like this:

<select [(ngModel)]="selectedItem">       
     <option *ngFor="let item of selectableItems"
             [ngValue]="item">
             {{item}}
     </option>
</select>

And then selectedItem will the the correct item from the list, including all it's properties.