Home > Software design >  Iterate a FormArray of FormGroups
Iterate a FormArray of FormGroups

Time:01-03

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> 

CodePudding user response:

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

  • Related