I'd like to bind a select element to a list of objects -- which is easy enough:
@Component({
selector: 'myApp',
template:
`<h1>My Application</h1>
<select [(ngModel)]="selectedValue">
<option *ngFor="#c of countries" value="c.id">{{c.name}}</option>
</select>`
})
export class AppComponent{
countries = [
{id: 1, name: "United States"},
{id: 2, name: "Australia"}
{id: 3, name: "Canada"},
{id: 4, name: "Brazil"},
{id: 5, name: "England"}
];
selectedValue = null;
}
In this case, it appears that selectedValue
would be a number -- the id of the selected item.
However, I'd actually like to bind to the country object itself so that selectedValue
is the object rather than just the id. I tried changing the value of the option like so:
<option *ngFor="#c of countries" value="c">{{c.name}}</option>
but this does not seem to work. It seems to place an object in my selectedValue
-- but not the object that I'm expecting. You can see this in my Plunker example.
I also tried binding to the change event so that I could set the object myself based on the selected id; however, it appears that the change event fires before the bound ngModel is updated -- meaning I don't have access to the newly selected value at that point.
Is there a clean way to bind a select element to an object with Angular 2?
<h1>My Application</h1>
<select [(ngModel)]="selectedValue">
<option *ngFor="let c of countries" [ngValue]="c">{{c.name}}</option>
</select>
StackBlitz example
NOTE: you can use [ngValue]="c"
instead of [ngValue]="c.id"
where c is the complete country object.
[value]="..."
only supports string values[ngValue]="..."
supports any type
update
If the value
is an object, the preselected instance needs to be identical with one of the values.
See also the recently added custom comparison https://github.com/angular/angular/issues/13268 available since 4.0.0-beta.7
<select [compareWith]="compareFn" ...
Take care of if you want to access this
within compareFn
.
compareFn = this._compareFn.bind(this);
// or
// compareFn = (a, b) => this._compareFn(a, b);
_compareFn(a, b) {
// Handle compare logic (eg check if unique ids are the same)
return a.id === b.id;
}
This could help:
<select [(ngModel)]="selectedValue">
<option *ngFor="#c of countries" [value]="c.id">{{c.name}}</option>
</select>
You can do this too without the need to use [(ngModel)]
in your <select>
tag
Declare a variable in your ts file
toStr = JSON.stringify;
and in you template do this
<option *ngFor="let v of values;" [value]="toStr(v)">
{{v}}
</option>
and then use
let value=JSON.parse(event.target.value)
to parse the string back into a valid JavaScript object
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With