Asaduzzaman Noor
Asaduzzaman Noor

Reputation: 199

FormGroup is not working in FormArray

I have a person class.

   export class Person {
        public name: Name;
        public childList: Person[];
        public string: gender;
        // Other Attribute

        constructor(person?)
        {
            person = person || {};
            this.name = person.name || {};
            this.gender = person.gender || {};
            this.childList = person.childList || [{}];
        }
    }

and Name class contains:

 export class Name {
    public firstName?: string;
    public lastName?: string;

    constructor(name?)
    {
        name = name || {};
        this.firstName = name.firstName || null;
        this.lastName = name.lastName || null;
    }
}

One part of the person component is:

   createChildInfoForm() {
    this.childInfoForm = this.formBuilder.group({
      childList: this.formBuilder.array([]),
    });
  }

  insertChildInfoForm() {
    this.setChildren(this.employee.childList);
  }

  get childList(): FormArray {
    return this.childInfoForm.get('childList') as FormArray;
  }

  setChildren(children: Person[]) {
    const childFGs = children.map(child => this.formBuilder.group(child));
    const childFormArray = this.formBuilder.array(childFGs);
    this.childInfoForm.setControl('childList', childFormArray);
  }

  addChild() {
    this.childList.push(this.formBuilder.group(new Person()));
  }

  removeChild(i: number) {
    const control = <FormArray>this.childInfoForm.controls['childList'];
    control.removeAt(i);
  }

Now the HTML is:

    <div formArrayName="childList" class="well well-lg">
      <div *ngFor="let child of childList.controls; let i=index" [formGroupName]="i" >
        <fieldset>
          <legend>Child # {{i + 1}}
            <mat-icon style="font-size: 15px; padding-left: 5px" *ngIf="childInfoForm.controls.childList.controls.length > 1" (click)="removeChild(i)">cancel</mat-icon>
          </legend>

          <!-- The repeated child template -->
          <div formGroupName="name"> <!-- Cannot find control with path: 'childList -> 0 -> name -> firstName' -->
            <mat-form-field class="w-100-p" fxFlex="100">
              <input matInput  formControlName="firstName" placeholder="Child Name">
            </mat-form-field>
          </div>

                <mat-form-field class="w-100-p" fxFlex="100"> <!-- Its Working -->
                  <input matInput  formControlName="gender" placeholder="Child Name">
                </mat-form-field>

        </fieldset>
        <br/><br/>
        <!-- End of the repeated address template -->
      </div>

      <button mat-raised-button class="save-employee-button mat-white-bg mt-16 mt-sm-0" (click)="addChild()">
        <span>Add CHILD</span>
      </button>
    </div>

When I am clicking the 'ADD CHILD Button' a new form is added. But the error is

Cannot find control with path: 'childList -> 0 -> name -> firstName'.

But for the 'gender' person -> gender is working. I am not sure why formGroupName is not working on Name object.

How to get the name -> firstName from the HTML?

I am a beginner in Angular.

Upvotes: 1

Views: 1402

Answers (1)

Pierre Mallet
Pierre Mallet

Reputation: 7221

You cant just do this.childList.push(this.formBuilder.group(new Person())); because your have a nested formGroup for name attribute of Person class

you could do :

addChild() {
    const PersonFormGroup = this.formBuilder.group({
        name: this.formBuilder.group({
            firstName: [null],
            lastName: [null]
        }),
        // or name: this.formBuilder.group(new Name()), # but i think its not very readable 
        gender: [null],
        childList: this.formBuilder.array([])
    });
    this.childList.push(PersonFormGroup);
  }

Upvotes: 1

Related Questions