Angular formArray doesn't render working mat-radio-group

498 Views Asked by At

These are form elements that don't work properly with the formArray. They render, but clicking on a button does nothing. The editChoice() event does not seem to happen if I put a break point in it.

The controls also don't change their button state visibly.

<form [formGroup]="myForm" class="dialogContent">
    <ng-container formArrayName="choices">
        <div class="control" *ngFor="let value of myForm.controls.choices?.value; let i=index">
            <ng-container [formGroupName]="i">
                 <label class="req" [id]="choiceList[i].id + '_label'">
                      {{ choiceList[i].label }}
                 </label>
                 <mat-radio-group attr.aria-label="{{choiceList[i].label}}" 
                  attr.index="{{i}}" 
                  formControlName="choice" [value]=choiceList[i].value?
                  (click)="editChoice($event)"
                  attr.aria-labelledby="{{choiceList[i].id + '_label'}}">
                       <mat-radio-button value="Y">Yes</mat-radio-button>
                       <mat-radio-button value="N">No</mat-radio-button>
                  </mat-radio-group>
             </ng-container>
        </div>
    </ng-container>
</form>

In constructor (or in ngInit, it doesn't seem to matter):

this.myForm = this.fb.group({
    otherControl: [''],
    otherDescription: [''],
    electronicSignature : ['', [Validators.required]],
    choices: this.fb.array([]) 
});

array to be rendered:

choiceList: Array<any> = [
   {
       value: "Y",
       id: "choiceA",
       label: "Choice A Text"
   },{
       value: "N",
       id: "choiceB",
       label: "Choice B Text"
    } 
    //(and several more like this)
];

in ngInit:

const choices = this.myForm.controls.choices as FormArray;
for (let i=0; i < this.choiceList.length; i++) {
    choices.push(this.fb.group ({ 
        choice: ['', [Validators.required]]
    }));
}

There are no debug errors, unless there is some way to turn something on to not hide whatever is wrong.

2

There are 2 best solutions below

5
On

Apparently the for loop in your template is cause the issue, when you loop over myForm.controls.choices?.controls instead of myForm.controls.choices?.value it works.

I can't really tell you why it isn't working so hoping someone can jump in to explain what's happening here.

0
On

It also helps to have a function on the typescript side that returns the object as a FormArray. When you get it by myForm.controls.choices it is typed as a control.

getChoices(): FormArray { 
   return myForm.controls.choices as FormArray; 
}