I have a select list which I want to intialise to a saved value returned from the server. But whatever I try I cannot get it to use the selected value.
I am using Angular 2.2.0 and Reactive Forms.
Here is list of values for the select list.
private categoryList: ICategory[] = [
new Category({ id: 1, name: 'Cat 1' }),
new Category({ id: 2, name: 'Cat 2' }),
new Category({ id: 3, name: 'cat 3' })
];
The saved value is:
{ id: 1, name: 'Cat 1' }
Using FormBuilder I create the form
this.itemForm = this.fb.group({
name: [null, Validators.required],
description: [null, Validators.required],
weight: [null, Validators.required],
dimensions: [null, Validators.required],
category: [null, Validators.required]
});
I then initialise it with the saved data
(<FormGroup>this.itemForm)
.setValue({
name: item.name,
description: item.description,
weight: item.weight,
dimensions: item.dimensions,
category: item.category
}, { onlySelf: true });
The template looks like this
<select name="category" [formControl]="itemForm.controls['category']">
<option [selected]="itemForm.controls['category'].value == null" value="">-- Select --</option>
<option *ngFor="let cat of categories" [ngValue]="cat">
{{cat.name}}
</option>
</select>
{{itemForm.controls['category'].value | json }}
Expected Result The name of item one is selected in the select and matches the text in the JSON displayed under template
Actual Behaviour The JSON shows this:
{ "id": 1, "name": "Cat 1" }
But nothing is selected in the select
If --Select-- is chosen the JSON updates correctly to "".
If another cat is chosen, the JSON also updates correctly.
What am I doing wrong, how do initialise the select?
EDIT I also tried this:
<option *ngFor="let cat of categories" [selected]="itemForm.controls['category'].value.id == cat.id" [ngValue]="cat">
If I understand you correctly, you want to set an default value. Then you could just refer to your item.category
+ the index of the value you want to set.
I would set the values like this, where we set the first item as a default value.
setValues() {
this.itemForm
.setValue({
name: item.name,
category: item.category[0].id
})
}
and then use formGroup
and formControlName
in the form, so:
<form [formGroup]="itemForm">
<input formControlName="name"/>
<small *ngIf="!itemForm.controls.name.valid">Name is required!</small>
<!-- More code -->
<select formControlName="category">
<! -- set ngValue to cat.id --> instead of just cat!
<option *ngFor="let cat of categories" [ngValue]="cat.id">
{{cat.name}}
</option>
</select>
</form>
Set the [ngValue]
(or use just [value]
) to either cat.name
or cat.id
depending on what you want to use, so if you are using ngValue
, that doesn't bind the whole object!
Here is a working Plunker. Not knowing where you set the values, at which point, I have made a setValues
-button in the plunker that mimics if the values are set later.
Hope this help!