0

Am trying to add dynamic fields in form formgroup where i need to add a formarray inside the from array with in that form group, I have tried but am geeting the following error

error_handler.js:54 EXCEPTION: Error in ./AppComponent class AppComponent - inline template:6:16 caused by: Cannot read property 'push' of undefined

please help me to resolve this issue thanks in advance

here is the plunkr

Component.ts

import { Component } from '@angular/core';
import { FormGroup, FormBuilder, FormArray, ReactiveFormsModule } from "@angular/forms";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  public formGroupz: FormGroup;
  constructor(private frmbldr: FormBuilder) { }
  private fieldIdentifier: any;
  items: any[] = [];
  ngOnInit() {
    //Called after the constructor, initializing input properties, and the first call to ngOnChanges.
    //Add 'implements OnInit' to the class.
    this.formGroupz = this.frmbldr.group({
      main:this.frmbldr.array([this.initRules()])
    })
  }
  initRules(){
      return this.frmbldr.group({
      ifgroup: this.frmbldr.array([]),
      truegrp: this.frmbldr.array([]),
      falsegrp: this.frmbldr.array([])
    })
  }
  ifFields() {
    debugger
    return this.frmbldr.group({
      conditionfields: ['']
    })
  }
  initextraField() {
    debugger
    if (this.fieldIdentifier == "true") {
      return this.frmbldr.group({
        truefields: ['']
      })
    }
    else if (this.fieldIdentifier == "false") {
      return this.frmbldr.group({
        falsefields: ['']
      })
    }
  }
  addiffields() {
    debugger
    this.fieldIdentifier = "if";
    const control = <FormArray>this.formGroupz.controls['main']['controls']['ifgroup'];
    const addrCtrl = this.ifFields();
    control.push(addrCtrl);
  }
  addtruefields() {
    debugger
    this.fieldIdentifier = "true";
    const control = <FormArray>this.formGroupz.controls['truegrp'];
    const addrCtrl = this.initextraField();
    control.push(addrCtrl);
  }
  addfalsefields() {
    this.fieldIdentifier = "false";
    const control = <FormArray>this.formGroupz.controls['falsegrp'];
    const addrCtrl = this.initextraField();
    control.push(addrCtrl);
  }
}

Component.html

<div [formGroup]="formGroupz">
    <div class="tab-pane">
        <!--<button (click)="addiffields()">addIf</button>-->
        <div class="panel panel-default m-b-10 m-t-0">
            <div class="panel-heading" style="padding: 5px 8px;background-color: #e1f5fe;">
                <span>if</span>
                <span (click)="addiffields()" class="material-icons pull-right icon-panel">add_circle</span>
            </div>
            <div class="panel-body p-t-0 p-b-0" formArrayName="main">
                <div *ngFor="let maingroup of formGroupz.controls.main.controls; let i =index">
                    <div [formGroupName]="i">
                        <div *ngFor="let ifgroup of formGroupz.controls.ifgroup.controls; let i =index">
                            <div [formGroupName]="i">
                                <input type="text" formControlName="conditionfields">
                            </div>
                        </div>

                    </div>
                </div>
            </div>
        </div>
        <div class="panel panel-default m-b-10 m-t-0">
            <div class="panel-heading" style="padding: 5px 8px;background-color: #e1f5fe;">
                <span>True</span>
                <span (click)="addtruefields()" class="material-icons pull-right icon-panel">add_circle</span>
            </div>
            <div class="panel-body p-t-0 p-b-0" formArrayName="main">
                <div *ngFor="let maingroup of formGroupz.controls.main.controls; let i =index">
                    <div [formGroupName]="i">
                        <div *ngFor="let trgrp of formGroupz.controls.truegrp.controls; let i =index">
                            <div [formGroupName]="i">
                                <input type="text" formControlName="conditionfields">
                            </div>
                        </div>

                    </div>
                </div>
            </div>
        </div>
        <div class="panel panel-default m-b-10 m-t-0">
            <div class="panel-heading" style="padding: 5px 8px;background-color: #e1f5fe;">
                <span>false</span>
                <span (click)="addfalsefields()" class="material-icons pull-right icon-panel">add_circle</span>
            </div>
            <div class="panel-body p-t-0 p-b-0" formArrayName="main">
                <div *ngFor="let maingroup of formGroupz.controls.main.controls; let i =index">
                    <div [formGroupName]="i">
                        <div *ngFor="let flgrp of formGroupz.controls.falsegrp.controls; let i =index">
                            <div [formGroupName]="i">
                                <input type="text" formControlName="falsefields">
                            </div>
                        </div>

                    </div>
                </div>
            </div>
        </div>
        {{formGroupz.value | json}}
    </div>
</div>
2
  • where did you call function initRules? Commented Aug 16, 2017 at 7:51
  • @Pengyy now check it I have updated the code Commented Aug 16, 2017 at 7:54

1 Answer 1

2

You are getting this error because your current structure is like below:

formGroupz(FormGroup)
    |----main(FormArray)               <------- mention here main is FormArray
           |----ifgroup(FormArray)
           |----truegrp(FormArray)
           |----falsegrp(FormArray)

If you want to access sub formArray ifgroup and same for truegrp and falsegrp, you can achieve it by below syntax with formArray index(same syntax for template but without this):

this.formGroupz.get('main').controls[0].get('ifgroup')
// or
this.formGroupz.controls.main.controls[0].controls.ifgroup

Also make sure your template are pairing to your form structure.

refer Plunker Demo(fixed template form structure).


BTW, if you don't need the first layer formArray, here is a simpler Plunker demo which changed main to formGroup.

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

2 Comments

am getting Cannot find control with path error, your plunkr is working correctly when i apply it to my code its not am getting error
@MBalajivaishnav you have to follow the structure defined in your component. And access sub formArray step by step. BTW, if my answer solved your problem, please consider accept it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.