1

I need your help. I am learning AngularJs. I am trying to do Add new row dynamically with Nested FormArray in AngularJs. I write code and It is running fine but there is an error in it. When I click on Add new Row button, It takes 4-5 times click to preform for it's task. When I am checking on console it shows these errors:

core.js:6185 ERROR Error: Cannot find control with name: '1'
    at _throwError (forms.js:3479)
    at setUpFormContainer (forms.js:3451)
    at FormGroupDirective.addFormGroup (forms.js:7581)
    at FormGroupName.ngOnInit (forms.js:6388)
    at callHook (core.js:4686)
    at callHooks (core.js:4650)
    at executeInitAndCheckHooks (core.js:4591)
    at refreshView (core.js:11814)
    at refreshDynamicEmbeddedViews (core.js:13154)
    at refreshView (core.js:11819)

    core.js:6185 ERROR Error: Cannot find control with path: '1 -> Name'
    at _throwError (forms.js:3479)
    at setUpControl (forms.js:3303)
    at FormGroupDirective.addControl (forms.js:7551)
    at FormControlName._setUpControl (forms.js:8367)
    at FormControlName.ngOnChanges (forms.js:8288)
    at FormControlName.wrapOnChangesHook_inPreviousChangesStorage (core.js:26853)
    at callHook (core.js:4690)
    at callHooks (core.js:4650)
    at executeInitAndCheckHooks (core.js:4591)
    at refreshView (core.js:11814)

my .html code is

<div class="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6 form-bg">
                <h2 class="mb-3">Add new row dynamically with Nested FormArray</h2>
                <form novalidate [formGroup]="FormGroup">
                <ng-container *ngIf='FormGroup.controls.itemRows!=null'>
                    <div *ngFor="let itemrow of FormGroup.controls.itemRows['controls']; let i=index;" [formGroupName]="i+1">
                        <div class="row">
                            <div class="col-12 col-md-2 form-group">
                                <input type="text" class="form-control" matInput placeholder="Name" formControlName="Name" >
                            </div>
                            <div class="col-12 col-md-2 form-group">
                                <input type="text" class="form-control" matInput placeholder="Roll No" formControlName="RollNo" >
                            </div>
                            <div class="col-12 col-md-2 form-group">
                                <input type="text" class="form-control" matInput placeholder="Class" formControlName="Class" >
                            </div>
                            <div class="col-12 col-md-2 form-group">
                                <input type="text" class="form-control" matInput placeholder="Mobile No" formControlName="MobileNo" >
                            </div>
                            <div class="col-12 col-md-2 form-group">
                             <button class="btn btn-danger" (click)="deleteRow(i)" >X</button>
                            </div>
                        </div>
                    </div>
                </ng-container>
                <div class="form-group pull-right">
                    <button class="btn btn-success" type="button" (click)="addNewRow()" [disabled]="FormGroup.invalid">
                        Add More
                    </button>
                </div>
            </form>
            </div>

and my .ts code is:

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

@Component({
  selector: 'app-reactiveform',
  templateUrl: './reactiveform.component.html',
  styleUrls: ['./reactiveform.component.css']
})
export class ReactiveformComponent implements OnInit {


  FormGroup: FormGroup;
  TotalRow : number;

}

  constructor( private _fb: FormBuilder) { }

ngOnInit(): void {

this.FormGroup = this._fb.group({
     itemRows: this._fb.array([this.initItemRow()])
   });

  }


  initItemRow(){
    return this._fb.group({
     Name: [''],
     RollNo: [''],
     Class: [''],
     MobileNo: ['']
    });
  }

  addNewRow(){
    const control = <FormArray>this.FormGroup.controls['itemRows'];
    control.push(this.initItemRow());
  }

  deleteRow(index: number){
    const control = <FormArray>this.FormGroup.controls['itemRows'];
    if(control != null){
      this.TotalRow = control.value.length;
    }
    if(this.TotalRow > 1){
      control.removeAt(index);
    } else{
      alert ("One Record Mandatory");
      return false;
    }

  }

1 Answer 1

1

You are using FormArray, hence you have to use formArrayName(with its name itemRows) directive before going for nesting of its inner item

 |- FormGroup
   |- FormArray
     |- FormGroup 1
     |- FormGroup 2

HTML

<form novalidate [formGroup]="FormGroup">
  <ng-container *ngIf='FormGroup.controls.itemRows!=null'>
     <div formArrayName="itemRows">
        <div *ngFor="let itemrow of FormGroup.controls.itemRows['controls']; let i=index;" [formGroupName]="i">
        ...
        ...
     </div>
  </ng-container>
</form>

Also note that [formGroupName] name was doing i+1 index. Since it is FormArray, change it to [formGroupName]="i"

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

2 Comments

you shouldn't add +1 to the index. BTW, when we mannage a FormArray in Angular is good has a getter: 'get itemRowsArray(){ return this.FormGroup.get('itemsRows') as FormArray}" and use *ngFor="let grop of itemsRowArray.controls";let i=index; [formGroupName]="i"
@Eliseo my bad. I missed that mistake. Thanks for heads up. You have an eagle eye :)

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.