Home > Software engineering >  Get boolean value form radio button on Reactive Form Angular
Get boolean value form radio button on Reactive Form Angular

Time:12-28

I've this simple form on my Angular component.

  user: UserDTO;
  name: FormControl;
  attendee: FormControl;
  attendeeForm: FormGroup;

  constructor(
    private fb: FormBuilder,
  ) {
    this.user = new UserDTO('', '', '', 2, true);

    this.name = new FormControl(this.user.name, [
      Validators.required,
      Validators.minLength(3),
      Validators.maxLength(55),
    ]);

    this.attendee = new FormControl(this.user.attendee, Validators.required);

    this.attendeeForm = this.fb.group({
      name: this.name,
      status: 2,
      attendee: this.attendee,
    });
  }

And this is the HTML:

<h2>Formulari de registre</h2>
<form (ngSubmit)="registerAttendee()" [formGroup]="attendeeForm"  >
  <mat-form-field >
     <input type="name" matInput placeholder="Name" required [formControl]="name">
  </mat-form-field>
  <div *ngIf="name.errors">
  <span style="color: red" *ngIf="name.errors && (name.touched || name.dirty)">
    <span *ngIf="name.errors['required']">El nom és requerit</span>
    <span *ngIf="name.errors['minlength']">El nom ha de tenir al menys tres caràcters</span>
    <span *ngIf="name.errors['maxlength']">El nom pot tenir màxim 55 caràcters</span>
  </span>
  </div>

  <p>Assistiràs?</p>
  <mat-radio-group aria-label="attendee">
     <mat-radio-button [value]="true" [formControl]="attendee">Sí</mat-radio-button>
     <mat-radio-button [value]="false" [formControl]="attendee">No</mat-radio-button>
  </mat-radio-group>
               
  <button type="submit" mat-raised-button color="primary [disabled]="!attendeeForm.valid">
     Enviar 
  </button>
</form>

How can I get the value of this radio button?

The result is always true because it takes it from new User by default. I have tried to do the same without starting the user but it doesn't work either. I have also read that the values received from a radio-button are of type "string", maybe this is the problem.

Surely it is a simple question but I don't know how to achieve it.

CodePudding user response:

I think you need to set formControlName="attendee" on mat-radio-group. At the same time you can remove [formControl]="attendee" on the mat-radio-button-elements.

I made a minimal example where I log the selected radio-button-value when the form is submitted. Moreover I added some code that logs every change in the attendee-FormControl (You don't need this part of the code in your final version: It's just for you to see in the console that my solution actually works).

The TS-File:

constructor(private fb: FormBuilder) { 

    // Code omitted for brevity

    this.attendeeForm = this.fb.group({
        attendee: this.attendee,
    });

    // JUST FOR DEBUGGING (not needed in final code):
    // Log every change in the 'attendee'-FormControl:
    this.attendeeForm.get('attendee')?.valueChanges.subscribe(value => {
        console.log('Selected radio-button-value', value);
    });
}

onSubmit() {
    // Log the selected radio-button value on submit:
    const attendee = this.attendeeForm.get('attendee')?.value;
    console.log('Selected radio-button-value:', attendee);
}

And then the HTML-File:

<form [formGroup]="attendeeForm" (ngSubmit)="onSubmit()">
    <mat-radio-group formControlName="attendee">
        <mat-radio-button [value]="true">Si</mat-radio-button>
        <mat-radio-button [value]="false">No</mat-radio-button>
    </mat-radio-group>
    <br>
    <button type="submit">Submit</button>
</form>

CodePudding user response:

You're mixing the constructor of a FormGroup and FormBuilder, and FormControl and FormControlName.

See the diferences (in the docs)

//using the constructor
//see that you use the way: property:new FormControl(...)
this.attendeeForm=new FormGroup({
   name:new FormControl(this.userName,[Validators.required,
                                       Validators.minLength(3),
                                       Validators.maxLength(55)],
   status:new FormControl(2),
   attendee:new FormControl(this.user.attendee, Validators.required);
   
})

Using FormBuilder

this.attendeeForm=this.fb.group({
   name:[this.userName,[Validators.required,
                                       Validators.minLength(3),
                                       Validators.maxLength(55)]],
   status:[2],
   attendee:[this.user.attendee, Validators.required];

In any case you have a FormGroup of FormControls. To use binding of a FormControl you use [formControl]

<!--see that you use [formControl] between [ ]-->
<input [formControl]="control">

but if you have a formGroup you use, under formGroup formControlName

<!--see that you use [formGroup] betwee [  ]-->
<form [formGroup]="attendeeForm">
    <!--but formControlName goes without [ ]-->
   <input formControlName="name">
</form>

See that you can use in .html

<pre>
{{attendeeForm?.value|json}}
</pre>

to see the value of your formGroup and you can use form.value.attendee or form.get('attendee').value to known the value of a FormControl that belong to a FormGroup

It's not neccessary subscribe to valueChange to know the value. You subscribe if you want to do "something" when change, but not to know the value.

  • Related