I'm trying to bind a mat-select to an enum value like this:
<mat-form-field>
<mat-label>Type</mat-label>
<mat-select [(ngModel)]="selectedType" [compareWith]="compareType">
<mat-select-trigger>
{{types[selectedType]?.name}}
</mat-select-trigger>
<mat-option *ngFor="let type of types | keyvalue" [value]="type.key">
<mat-icon>{{type.value.icon}}</mat-icon> {{type.value.name}}
</mat-option>
</mat-select>
</mat-form-field>
And the typescript:
enum Type {
Hardware = 0,
Software = 1
}
types: { [TP in number]: { icon: string, name: string }; } = {
[Type.Hardware]: { icon: 'computer', name: 'Hardware' },
[Type.Software]: { icon: 'keyboard', name: 'Software' },
};
selectedType: Type;
compareType(type1: Type, type2: Type): boolean {
return ((type1 as Type) === (type2 as Type));
}
I want the value of the select to be bound to selectedType
, which I'm trying to achieve using [(ngModel)]="selectedType" [compareWith]="compareType"
.
The problem is, that this data-binding doens't fully go both ways. When I assign a value using the UI, the binding updates accordingly, but when I update the value inside my code, it resets the value in the UI, showing the placeholder again. However while the UI doesn't display it correctly, the value is assigned properly.
there is type mismatch problem in your code.
selectedType
has type Type
which is a number.
where you set[value]="type.key"
within
<mat-option *ngFor="let type of types | keyvalue" [value]="type.key">
type.key
is a string due to keyvalue
pipe.
in the code above when you a select an item from dropdown as string value of "0" or "1" is assigned to selectedType
. if you assign a value programatically like this.selectedType = Type.Hardware
a number value 0
is assigned to selectedType
and since your compareType
function uses strict equality (===) it returns false because 1 === "1"
is false
you can either;
enum Type
have string values;enum Type {
Hardware = "0",
Software = "1"
}
type.key
to number while binding to mat-option
[value]="+type.key"
compareType
function. (i personally do not recommend this one!) compareType(type1: Type, type2: Type): boolean {
return ((type1 as Type) == (type2 as Type));
}
here is a working demo