FormGroup containing Radio Buttons with an Angular FormArray

Sammy picture Sammy · Jan 14, 2018 · Viewed 9.1k times · Source

I have the following code that dynamically adds a form group containing a title and two radio buttons to create a condition, effectively providing its title and whether or not it's an acceptable condition:

The problem is that when clicking the ADD A NEW CONDITION button, and the new form group appears, every time I select any radio button in the group array, the corresponding radio button of the first array item in the group is the one that gets selected.

Answer

R. Richards picture R. Richards · Jan 14, 2018

What you need to consider when looping through an array group is the id and name you assign to each one. You currently have your input id and name getting set to the same value in each loop.

You would need to use the i variable you have available to make the id and name for each input a dynamic value, like below:

<div [formGroup]="form">
  <div *ngIf="conditions" formArrayName="conditions">

    <div *ngFor="let condition of conditions.controls; let i=index" [formGroupName]="i">

      <input class="form-control" formControlName="title" type="text" placeholder="title">

      <div class="custom-control custom-radio custom-control-inline">
        <input type="radio" id="{{ 'acceptable' + i}}" formControlName="acceptability"
            class="custom-control-input" [value]="ACCEPTABILITY.ACCEPTABLE">
        <label class="custom-control-label" for="{{ 'acceptable' + i}}">Acceptable</label>
      </div>

      <div class="custom-control custom-radio custom-control-inline">
        <input type="radio" id="{{ 'unacceptable' + i}}" formControlName="acceptability"
            class="custom-control-input" [value]="ACCEPTABILITY.INACCEPTABLE">
        <label class="custom-control-label" for="{{ 'unacceptable' + i}}">Unacceptable</label>
      </div>

    </div>

    <button type="button" class="btn btn-outline-dark btn-block" (click)="addCondition()">
            <i class="fa fa-plus fa-lg mr-3"></i>ADD A NEW CONDITION</button>
  </div>
</div>

<div>
  <pre>{{ form.value | json }}</pre>
</div>

Notice the string interpolation for the name and id attributes. Same goes for the for attribute in the labels.

You may have to play around with this to get is exactly where it needs to be. (I didn't test it thoroughly)

Hope this helps.