Reputation: 2903
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?
Upvotes: 3
Views: 1371
Reputation: 657018
[value]
only supports string vales as the bound value. Use [ngValue]
instead, it can bind objects.
Upvotes: 3
Reputation: 6791
i have same issue, you can try my solution:
<select class="form-control custom-select" id="store" name="store" required
[(ngModel)]="selectedStore" (change)="selectionChanged($event.target.value)">
<option *ngFor="let s of stores; let i = index" value="{{i}}">{{s.name}}</option>
</select>
// .ts
selectionChanged(value: any){
// this.selectedStore = position in stores
console.log(this.stores[this.selectedStore]);
}
Upvotes: -1