Home > Software engineering >  Why can't I select a radio button in this Angular Material app?
Why can't I select a radio button in this Angular Material app?

Time:01-21

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

  1. What am I doing wrong?
  2. 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>

  • Related