2

i'm using angular 2.4 and need to make dynamic forms using "FormArray" but the HTML doesn't recongnize my arrays at all. i've got an error like this: caused by: Cannot find control with name: '0'

ts file :

    import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators, FormArray } from '@angular/forms';

@Component({
  selector: 'my-formstwo',
  templateUrl: "app/fromstesttwo/fromstesttwo.component.html",
})
export class FromstesttwoComponent  {

    myForm: FormGroup;
    constructor(){
        this.myForm = new FormGroup({
            'dataforms': new FormGroup({
                'username': new FormControl('sh', [Validators.required,Validators.minLength(3)]),
                'email': new FormControl('', 
                    [
                        Validators.required, 
                        Validators.pattern("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")
                    ])
                }),
            'password': new FormControl('', Validators.required),
            'gender': new FormControl('Fmale',Validators.required),
            'hobys': new FormArray([
                new FormControl('SF')
            ])
        });
    }
    get hobyss(): FormArray { return this.myForm.get('hobys') as FormArray; }
    addHobys() {
     this.hobyss.push(new FormControl()); 
    }
    genders:Array<string> = [
        'Male',
        'Fmale'
    ]
    onSubmit(){
        console.log(this.myForm);
    }
}

html file :

<div class="clearfix"> </div>
<p> </p>
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<div formGroupName="dataforms">
 <div class="form-group">
    <label for="exampleInputEmail1">Username</label>
    <input 
      type="username" 
      class="form-control" 
      id="exampleInputEmail1" 
      placeholder="Username"
      formControlName="username">
  </div>

  <div class="form-group">
    <label for="exampleInputEmail1">Email address</label>
    <input 
      type="email" 
      class="form-control" 
      id="exampleInputEmail1" 
      placeholder="Email"
      formControlName="email">
      <div *ngIf="!myForm.controls.dataforms.controls.email.valid">
        email inValid
      </div>
  </div>
</div>


  <div class="form-group">
    <label for="exampleInputPassword1">Password</label>
    <input 
      type="password" 
      class="form-control" 
      id="exampleInputPassword1" 
      placeholder="Password"
      formControlName="password">
  </div>

  <div class="form-group">
    <div class="radiobottom" *ngFor="let g of genders">
      <input type="radio" name="gender" [value]="g" formControlName="gender">
      {{g}}
    </div>
  </div>


  <div FormArrayName="hobys">
    <div class="form-group" *ngFor="let h of myForm.controls.hobys.controls; let i=index">
     <p> </p>
        <input 
          type="text"
          class="form-control" 
          formControlName="{{ i }}">
    </div> 
  </div>

  <button type="button" class="btn btn-primary" (click)="addHobys()">Hoby</button>
  <button type="submit" class="btn btn-default" [disabled]="!myForm.valid">Submit</button>


</form>

my error console :

EXCEPTION: Error in app/fromstesttwo/fromstesttwo.component.html:53:10 caused by: Cannot find control with name: '0'
0

2 Answers 2

3

The issue is that it's formArrayName, not FormArrayName:

<div formArrayName="hobys">
  <div class="form-group" *ngFor="let h of myForm.controls.hobys.controls; let i = index">
    <p></p>
    <input type="text" class="form-control" formControlName="{{i}}">
  </div> 
</div>

Bonus:

As tip, you can create references for your controls in your component, as below:

export class FromstesttwoComponent {

  myForm: FormGroup;
  usernameCtrl: FormControl;
  emailCtrl: FormControl;
  passwordCtrl: FormControl;
  genderCtrl: FormControl;
  hobbiesCtrl: FormControl;
  dataFormsCtrl: FormGroup;
  hobbiesCtrl: FormArray;

  constructor() {
    this.usernameCtrl = new FormControl('sh', [Validators.required,Validators.minLength(3)]);
    this.emailCtrl = new FormControl('', 
      [
          Validators.required, 
          Validators.pattern("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")
      ]
    );
    this.passwordCtrl = new FormControl('', Validators.required);
    this.genderCtrl = new FormControl('Fmale',Validators.required);
    this.hobbiesCtrl = new FormArray([new FormControl('SF')]);

    this.dataFormsCtrl = new FormGroup({
      'username': this.usernameCtrl,
      'email': this.emailCtrl
    });

    this.myForm = new FormGroup({
      'dataforms': this.dataFormsCtrl, 
      'password': this.passwordCtrl, 
      'gender': this.genderCtrl, 
      'hobys': this.hobbiesCtrl 
    });
  }
}

Why?

Doing this you wouldn't need to use get or anything to access the controls, you just can access this directly in your template, as below:

Instead of:

<div *ngIf="!myForm.controls.dataforms.controls.email.valid">
...
<div class="form-group" *ngFor="let h of myForm.controls.hobys.controls; let i=index">

This:

<div *ngIf="emailCtrl.invalid">
...
<div class="form-group" *ngFor="let h of hobbiesCtrl.controls; let i=index">
Sign up to request clarification or add additional context in comments.

Comments

0

you have to change this FormArrayName="hobys" in this formArrayName="hobys" (lowercase)

and this formControlName="{{ i }}" in this [formControlName]="i"

1 Comment

Your first point is correct while the second is not. formControlName="{{ i }}" works on my case.

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.