I have a mat-select where the options are all objects defined in an array. I am trying to set the value to default to one of the options, however it is being left selected
Use a binding for the value in your template.
value="{{ option.id }}"
should be
[value]="option.id"
And in your selected value use ngModel
instead of value
.
<mat-select [(value)]="selected2">
should be
<mat-select [(ngModel)]="selected2">
Complete code:
<div>
<mat-select [(ngModel)]="selected2">
<mat-option *ngFor="let option of options2" [value]="option.id">{{ option.name }}</mat-option>
</mat-select>
</div>
On a side note as of version 2.0.0-beta.12 the material select now accepts a mat-form-field
element as the parent element so it is consistent with the other material input controls. Replace the div
element with mat-form-field
element after you upgrade.
<mat-form-field>
<mat-select [(ngModel)]="selected2">
<mat-option *ngFor="let option of options2" [value]="option.id">{{ option.name }}</mat-option>
</mat-select>
</mat-form-field>
My solution is little tricky and simpler.
<div>
<mat-select
[placeholder]="selected2">
<mat-option
*ngFor="let option of options2"
value="{{ option.id }}">
{{ option.name }}
</mat-option>
</mat-select>
</div>
I just made use of the placeholder. The default color of material placeholder is light gray
. To make it look like the option is selected, I just manipulated the CSS as follows:
::ng-deep .mat-select-placeholder {
color: black;
}
A comparison between a number and a string use to be false, so, cast you selected value to a string within ngOnInit and it will work.
I had same issue, I filled the mat-select with an enum, using
Object.keys(MyAwesomeEnum).filter(k => !isNaN(Number(k)));
and I had the enum value I wanted to select...
I spent few hours struggling my mind trying to identify why it wasn't working. And I did it just after rendering all the variables being used in the mat-select, the keys collection and the selected... if you have ["0","1","2"] and you want to select 1 (which is a number) 1=="1" is false and because of that nothing is selected.
so, the solution is to cast you selected value to a string within ngOnInit and it will work.
public options2 = [
{"id": 1, "name": "a"},
{"id": 2, "name": "b"}
]
YourFormGroup = FormGroup;
mode: 'create' | 'update' = 'create';
constructor(@Inject(MAT_DIALOG_DATA) private defaults: defautValuesCpnt,
private fb: FormBuilder,
private cd: ChangeDetectorRef) {
}
ngOnInit() {
if (this.defaults) {
this.mode = 'update';
} else {
this.defaults = {} as Cpnt;
}
this.YourFormGroup.patchValue({
...
fCtrlName: this.options2.find(x => x.name === this.defaults.name).id,
...
});
this.YourFormGroup = this.fb.group({
fCtrlName: [ , Validators.required]
});
}
<div>
<mat-select formControlName="fCtrlName"> <mat-option
*ngFor="let option of options2"
value="{{ option.id }}">
{{ option.name }}
</mat-option>
</mat-select>
</div>
You can simply implement your own compare function
[compareWith]="compareItems"
See as well the docu. So the complete code would look like:
<div>
<mat-select
[(value)]="selected2" [compareWith]="compareItems">
<mat-option
*ngFor="let option of options2"
value="{{ option.id }}">
{{ option.name }}
</mat-option>
</mat-select>
</div>
and in the Typescript file:
compareItems(i1, i2) {
return i1 && i2 && i1.id===i2.id;
}
TS
optionsFG: FormGroup;
this.optionsFG = this.fb.group({
optionValue: [null, Validators.required]
});
this.optionsFG.get('optionValue').setValue(option[0]); //option is the arrayName
HTML
<div class="text-right" [formGroup]="optionsFG">
<mat-form-field>
<mat-select placeholder="Category" formControlName="optionValue">
<mat-option *ngFor="let option of options;let i =index" [value]="option">
{{option.Value}}
</mat-option>
</mat-select>
</mat-form-field>
</div>