I have been developing an e-commerce app with Angular 14 and Angular Material.
I am working on a registration form that contains, among others, a set of radio buttons.
In the form component's Typescript file, I have:
import { FormService } from '../../services/form.service';
export class FormComponent implements OnInit {
constructor (
private formService: FormService
) { }
public accountTypes!: any;
public selectedAccountType: any;
ngOnInit(): void {
this.getAccountTypes();
}
public setAccountType() {
this.selectedAccountType = this.accountTypes[0].value;
};
public getAccountTypes() {
this.formService.getAccountTypes().subscribe(response => {
this.accountTypes = response;
if (this.accountTypes && this.accountTypes.length) {
this.setAccountType();
}
});
}
}
In the template:
<mat-radio-group name="account_type" [(ngModel)]="this.selectedAccountType">
<mat-radio-button *ngFor="let accountType of accountTypes" value="accountType.value" [checked]="accountType.checked">
<span >{{ accountType.label }}</span>
</mat-radio-button>
</mat-radio-group>
The problem
For a reason I was unable to understand, when I click a (radio) button, it does not stay selected.
Questions
- What am I doing wrong?
- What is the easiest and most reliable way to achieve the desired result?
CodePudding user response:
With mat-radio-button
and ngModel
you don't need to handle the checked
property. In your case it overrides it always with false
. You can read a lot in the official docu. Here is the right way (Stackblitz):
HTML:
<mat-radio-group [(ngModel)]="favoriteSeason">
<mat-radio-button *ngFor="let season of seasons" [value]="season">
{{season}}
</mat-radio-button>
</mat-radio-group>
<div >Your favorite season is: {{favoriteSeason}}</div>
And code:
@Component({
selector: 'radio-ng-model-example',
templateUrl: 'radio-ng-model-example.html',
styleUrls: ['radio-ng-model-example.css'],
})
export class RadioNgModelExample {
favoriteSeason: string;
seasons: string[] = ['Winter', 'Spring', 'Summer', 'Autumn'];
}
CodePudding user response:
Change the value
attribute to a property binding, that is [value]
not value
, it is required when using ngModel
.
ngModel
decides what is selected by comparing the [value]
to the [(ngModel)]
binding.
that is the [value]
of the mat-radio-button
with selectedAccountType
.
You can remove the checked
as it does not work with ngModel
and a default option is already being set in setAccountType()
method.
<mat-radio-group name="account_type" [(ngModel)]="this.selectedAccountType">
<mat-radio-button *ngFor="let accountType of accountTypes" [value]="accountType.value">
<span >{{ accountType.label }}</span>
</mat-radio-button>
</mat-radio-group>