Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 select with ngValue null

Tags:

angular

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?

like image 962
bensgroi Avatar asked Apr 21 '16 23:04

bensgroi


4 Answers

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>
like image 197
Omar Alejandro Martinez Sainz Avatar answered Nov 17 '22 13:11

Omar Alejandro Martinez Sainz


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
like image 4
Mikki Kobvel Avatar answered Nov 17 '22 12:11

Mikki Kobvel


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>`
like image 1
Brian Bjork Avatar answered Nov 17 '22 14:11

Brian Bjork


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

like image 1
Igor Avatar answered Nov 17 '22 12:11

Igor