Iterate a FormArray of FormGroups

Issue

I’m having trouble getting my form array of form groups to work.

I’d like to iterate over the form array and render the inputs in each form group. When I call addExercise() the template doesn’t render the new form group that I push to the form array. Also when I call saveWorkout() the console.log(this.workoutFormArray.value) line shows that the values from my inputs are not reflected.

workout.component.ts

workoutFormArray: FormArray;

ngOnInit() {
  this.workoutFormArray = new FormArray([
    new FormGroup({
      exercise: new FormControl(''),
      reps: new FormControl('')
    })
  ]);
}

addExercise() {
  this.workoutFormArray.push(
    new FormGroup({
      exercise: new FormControl(''),
      reps: new FormControl(''),
    })
  );
}

saveWorkout() {
  console.log(this.workoutFormArray.value);
}

workout.component.html

<ion-icon (click)="addExercise()" name="add" slot="end"></ion-icon>

<div [formArrayName]="workoutFormArray">
  <div *ngFor="let group of workoutFormArray.controls; let i = index">
    <div [formGroupName]="i">
      <ion-select 
        placeholder="Exercise"
        formControlName="group.controls.exercise"
        (ionChange)="saveWorkout()"
      >
        <ion-select-option [value]="pushups"> Pushups </ion-select-option>
        <ion-select-option [value]="squats"> Squats </ion-select-option>
      </ion-select>

      <ion-input 
        type="text"
        formControlName="group.controls.reps"
      ></ion-input>
    </div>
    <button type="button" (click)="saveWorkout()">Save</button>
  </div>
</div> 

Solution

Updated: You mentioned that the workoutFormArray FormArray is the root of the form, you may have a read on this reported issue in GitHub: Supporting [formArray] without a [formGroup] parent #30264.

<div [formGroup]="$any(workoutFormArray)">
  ...
</div>

The problem was that you provided the wrong formControlName to the nested FormGroup. It should be:

<ion-select
  placeholder="Exercise"
  formControlName="exercise"
  (ionChange)="saveWorkout()"
>
  <ion-select-option value="pushups"> Pushups </ion-select-option>
  <ion-select-option value="squats"> Squats </ion-select-option>
</ion-select>

<ion-input type="text" formControlName="reps"></ion-input>

Without the prefix group.controls..

Demo @ StackBlitz

Answered By – Yong Shun

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published