Search code examples
angularjsangularproperty-binding

Property binding to the object does not work in Angular 2


I'm having the very strange behavior with Angular 2 property binding.

Firstly, this is a Store class:

export class Store {
    id: number;
    name: string;
    address: string;
}

This is component code:

export class MyBuggyComponent implements OnInit {

  stores: Store[];
  selectedStore: any;
  error: any;

  constructor(private myDataService: MyDataService) { }

  ngOnInit() {
    this.myDataService.getStores().subscribe(
      stores => this.stores = stores,
      error => { this.error = error; console.log(this.error); });
  }

  selectionChanged(value: any){
    console.log("DEBUG: " + value);
  }
}

And here is the template that drives me nuts!

<form>
  <div class="form-group">
    <label for="store">Select store:</label>
    <select class="form-control custom-select" id="store" name="store" required 
      [(ngModel)]="selectedStore" (change)="selectionChanged($event.target.value)">
      <option *ngFor="let s of stores" [value]="s">{{s.name}}</option>
    </select>
    <small class="form-text text-muted" *ngIf="selectedStore">Address: {{selectedStore.address}}</small>
  </div>
</form>

Here the binding [value]="s" of the option of <select> tag just does not work! It sets selectedStore to some empty object(?), It displays empty Address: text in <small> tag, and it logs: DEBUG: [object Object] in console (in selectionChanged()). But the {{s.name}} interpolation works as expected (displays names inside select-box).

Now watch this: if I make following modification to the template, it just works as expected:

  <option *ngFor="let s of stores" [value]="s.address">{{s.name}}</option>
</select>
<small class="form-text text-muted" *ngIf="selectedStore">Address: {{selectedStore}}</small>

Now the binding works, the address is logged in console and also displayed in <small> tag properly. So the binding [value]="s" does not work (actually gives some weird 'object' value), but binding [value]="s.address" works as expected. I've followed the docs and there is no mention of such limitation. Is this a bug? Or am I missing something?


Solution

  • [value] only supports string vales as the bound value. Use [ngValue] instead, it can bind objects.