Angular 2 Accessing Nested FormArrays using FormBuilder

10,199

Try the following HTML:

<form [formGroup]="myForm" novalidate (ngSubmit)="onSubmit(myForm)">
    <div formArrayName="projects">
        <div [formGroupName]="i" *ngFor="let project of myForm.controls.projects.controls; let i = index">
            <md-input placeholder="Name" formControlName="name"></md-input>
            <div formArrayName="some_array">
                <div [formGroupName]="x" *ngFor="let some_obj of project.controls.some_array.controls; let x = index">
                    <div>
                        <md-input placeholder="Nome" formControlName="name"></md-input>
                        <small *ngIf="!some_obj.controls.name.valid">Nome é requerido</small>
                    </div>
                    <md-input type="number" placeholder="Cost" formControlName="attr" required></md-input>
                </div>
            </div>
        </div>
    </div>
    <button type="submit" md-raised-button color="primary" [disabled]="!myForm.valid">Submit</button>
</form>
<pre>form value: <br>{{myForm.value | json}}</pre>
Share:
10,199

Related videos on Youtube

Deepika Bhandari
Author by

Deepika Bhandari

Updated on September 15, 2022

Comments

  • Deepika Bhandari
    Deepika Bhandari almost 2 years

    First of all I just begin with Angular 2 and I'm trying to build a nested form and validate it.

    Here's part of my ts file:

    ngOnInit() {
      this.myForm = this.formBuilder.group({
        projects: this.formBuilder.array([
          this.initProjects()
        ])
      });
    }
    
    initProjects(): any {
      return this.formBuilder.group({
        name: ['', [Validators.required, Validators.minLength(3)]],
        some_array: this.formBuilder.array([
          this.formBuilder.group({
            name: ['', Validators.required],
            attr: ['', Validators.required],
            some_id: [1, Validators.required]
          })
        ])
      });
    }
    
    addProject(): void {
      const control = < FormArray > this.myForm.controls['projects'];
      control.push(this.initProjects());
    }
    

    View:

    <form [formGroup]="myForm" novalidate (ngSubmit)="onSubmit(myForm)">
      <div formArrayName="projects">
        <div *ngFor="let project of myForm.controls.projects.controls; let i = index">
          <div [formGroupName]="i">
            <md-input placeholder="Name" formControlName="name"></md-input>
          </div>
          <div *ngFor="let some_obj of project.controls.some_array.controls; let x = index">
            <div [formGroupName]="x">
              <div>
                <md-input placeholder="Nome" formControlName="controls.some_array.controls.name"></md-input>
                <small *ngIf="!some_obj.controls.name.valid">
                        Nome é requerido
                      </small>
              </div>
              <md-input type="number" placeholder="Cost" formControlName="controls.some_array.controls.attr" required></md-input>
            </div>
          </div>
        </div>
      </div>
      <button type="submit" md-raised-button color="primary" [disabled]="!myForm.valid">Submit</button>
    </form>
    <pre>form value: <br>{{myForm.value | json}}</pre>
    

    The output of form value:

    form value: 
    {
      "projects": [
        {
          "name": "",
          "some_array": [
            {
              "name": "",
              "attr": "",
              "some_id": 1
            }
          ]
        },
        {
          "name": "",
          "some_array": [
            {
              "name": "",
              "attr": "",
              "some_id": 1
            }
          ]
        }
      ]
    }
    

    Well, as you can see I have some arrays called projects, with 1 array inside each one.

    So the problem is that I'm not able to validate each control of some_array array.

    Actually I'm getting the following error:

    ORIGINAL EXCEPTION: Cannot find control with path: 'projects -> 0 -> controls.some_array.controls.name PS: I already tried to put it in a div, as below:

    But I also got an error:

    Cannot find control with path: 'projects -> some_array' Thanks in advance. Any help would be appreciated.