I'm trying to use a material select component that gets its values through an Observable with async pipe.
template:
<mat-form-field>
<mat-select
value="selectedOption$ | async"
(selectionChange)="onSelectionChange($event.value)">
@for (option of (optionList$ | async) ?? []; track option) {
<mat-option [value]="option">{{option.name}}</mat-option>
}
</mat-select>
</mat-form-field>
typescript:
...
export class SomeContainer {
private readonly someService = inject(SomeService);
readonly selectedOption$;
readonly optionList$;
constructor() {
this.selectedOption$ = this.someService.fetchOption$(
this.someService.getCurrentOptionId$(),
);
this.optionList$ = this.someService.getOptionList$();
}
onSelectionChange(option: Option): void {
this.someService.setSavedOption(option.optionId);
}
}
And in the service class, I just save the selected option into localstorage, as well as fetch the saved options from localstorage and fetch it. I'm able to see the list of options in the component as well as change select them, but the initial saved option doesn't display, and it's just an empty box. I've tried using behaviorsubject with a set initial value as well instead of simply an Observable, but the initial value is still not displayed.
I'm not sure what the issue is here, I'm expecting to see an initial option selected for the component, but it's not being shown. Any help would be appreciated.
Currently the value
binds selectedOption$ | async
as string instead of actual value.
You should use [value]
or [ngModel]
(one-way binding).
Besides, as you are attempting to bind the value with object, you should also implement the [compareWith]
to the <mat-select>
to ensure the previous selected object is bind correctly.
<mat-form-field>
<mat-select
[value]="selectedOption$ | async"
(selectionChange)="onSelectionChange($event.value)"
[compareWith]="compare">
@for (option of (optionList$ | async) ?? []; track option) {
<mat-option [value]="option">{{option.name}}</mat-option>
}
</mat-select>
</mat-form-field>
compare(device1: any, device2: any) {
return device1?.deviceId === device2?.deviceId;
}