Here's what I'm trying to do: I want a select list bound to an array of objects with ngValue, but the first option needs to be a "None" option with a null
value.
Model:
this.managers = [
{ id: null, name: "(None)" },
{ id: 1, name: "Jeffrey" },
{ id: 2, name: "Walter" },
{ id: 3, name: "Donnie" }
];
this.employee = {
name: "Maude",
managerId: null
};
View:
<select [(ngModel)]="employee.managerId">
<option *ngFor="#manager of managers" [ngValue]="manager.id">{{ manager.name }}</option>
</select>
On load, the list correctly binds to the "None" element. But if you change to a different item and back, the model value now switches to a string of 0: null
. This is pretty inconvenient; it means I have to intercept the value and change it to a null manually before I attempt to save it to the server.
Here's a Plunker with a demo: http://plnkr.co/edit/BH96RWZmvbbO63ZAxgNX?p=preview
This was pretty easily done in Angular 1 with an extra <option value="">None</option>
This seems like it would be a pretty common scenario, and yet I've been unable to find any solutions. I've also tried adding an <option [ngModel]="null">None</option>
, but it results in the same 0: null
value.
Any suggestions?
For me it is really looks like a bug, but I if you are looking for fast solution, you can simply convert null
identifier to string
. It should solve the problem but you should do some additional moves to make that work.
See example Plnkr example
Or if you are going to do that in the way you mention from ng1,
you can do like this: Plnkr example
I know that it is not best solution, but hope will help you before this bug will be fixed by NG team!
- https://github.com/angular/angular/issues/10349
- https://github.com/angular/angular/pull/12026
I will redirect you to TabascoMustang's reddit answer, I implement his solution and work magnificent:
TabascoMustang's reddit answer
this should work (updated for current ng2 rc):
<select [ngModel]="audit.managerId || ''" (ngModelChange)="audit.managerId = $event">
<option value="">Please Select</option>
<option *ngFor="let contact of audit.contacts">{{ contact.name }}
</option>
</select>
Instead of the string 'null' I created a blank object to compare to later on in my TypeScript.
In component:
blankObject = {
toString() {
return 'blank object';
}
};
isBlank() {
return this.filter.searchValue == null || this.filter.searchValue === this.blankObject;
}
In Template:
<select [(ngModel)]="filter.searchValue">
<option [ngValue]="blankObject"></option>
<option *ngFor="let item of filter.selectOptions" [ngValue]="item.value">
{{item.label}}
</option>
</select>`
As of now there is an open issue in the github repository for this.
As a work around I found adding ngModelChange
is the easiest way to set the value to null in the view without having to add anything to the component.
View:
<select [(ngModel)]="employee.managerId"
(ngModelChange)="employee.managerId = $event ? $event : null">
<option *ngFor="#manager of managers" [value]="manager.id">{{ manager.name }}</option>
</select>
note that ngValue
is now value
Change [ngValue] to just [value]