1

I have a simple reactive form with a FormArray that will contain FromGroups.

I know this has been asked many times, but I can't still figure out why it's not working. I've tried many ways. This is are two simplified examples put together with what I've read from the docs and found online.

Component:

@Component({
  selector: 'app-professional-info-form',
  templateUrl: './professional-info-form.component.html',
  styleUrls: ['./professional-info-form.component.scss']
})
export class ProfessionalInfoFormComponent implements OnInit {

  protected professionalInfo: FormGroup;

  constructor() { }

  ngOnInit() {
    this.initForm();
  }

  private initForm() {
    this.professionalInfo = new FormGroup({
      trainings: new FormArray([
        new FormGroup({
          institutionId: new FormControl(null, null),
          title: new FormControl(null, null),
          description: new FormControl(null, null),
          institution: new FormControl(null, Validators.required),
          grade: new FormControl(null, null),
          from: new FormControl(null, Validators.required),
          to: new FormControl(null, null)
        })
      ])
    });
   
  }

}   

HTML:

<form [formGroup]="professionalInfo" (ngSubmit)="onSubmit()" novalidate *ngIf="professionalInfo">
  <div formArrayName="trainings">
    <div *ngFor="let training of trainings.controls; index as t" [formGroupName]="t">
      <input type="text" [formControlName]="title" placeholder="Titolo" />
      <input type="text" [formControlName]="institution" placeholder="Istituto" />
      <input type="text" placeholder="Inizio" [formControlName]="from">
      <input type="text" placeholder="Fine" [formControlName]="to">
      <input type="text" placeholder="Voto" [formControlName]="grade" maxlength="5">
    </div>
  </div>
</form>

Console error:

ERROR TypeError: Cannot read property 'controls' of undefined
    at Object.eval [as updateDirectives] (ProfessionalInfoFormComponent.html:19)

If I add this method to the component:

get trainingsFormArray() {
    return (<FormArray>this.professionalInfo.get('trainings'));
  }

And edit the *ngFor like this:

<div *ngFor="let training of trainingsFormArray.controls; index as t" [formGroupName]="t">

The console error is:

ERROR Error: Cannot find control with path: 'trainings -> 0 -> '

Which is kind of crazy because if console.log 'trainingsFormArray' after initializing the form the output is the following:

console.log output

Every time I have to work with angular's reactive forms I encounter problems like this one. I can't seem to figure out a consistent way for making them work with dynamic controls like in this case. Please help me.

2 Answers 2

1

There's an issue in your template. Angular doesn't know what trainings is. Use professionalInfo.controls['trainings'].controls to have access to the controls in the trainings FormArray instead.

Something like this:

<form 
  [formGroup]="professionalInfo" 
  (ngSubmit)="onSubmit()" 
  novalidate 
  *ngIf="professionalInfo">
  <div formArrayName="trainings">
    <div 
      *ngFor="let training of professionalInfo.controls['trainings'].controls; index as t" 
      [formGroupName]="t">
      <input type="text" formControlName="title" placeholder="Titolo" />
      <input type="text" formControlName="institution" placeholder="Istituto" />
      <input type="text" placeholder="Inizio" formControlName="from">
      <input type="text" placeholder="Fine" formControlName="to">
      <input type="text" placeholder="Voto" formControlName="grade" maxlength="5">
    </div>
  </div>
</form>

Here's a Working Sample StackBlitz for your ref.

Sign up to request clarification or add additional context in comments.

Comments

1

You are using [formControlName]='title' , this would need the title to be a variable with the control name. You can get rid of the enclosing []and it would work fine. Use as:

formControlName='title'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.