I am trying to iterate over a formArray in my component but I get the following error

Error: Cannot find control with unspecified name attribute

Here is what the logic looks like on my class file

export class AreasFormComponent implements OnInit { public initialState: any; public areasForm: FormGroup; constructor(private fb: FormBuilder) { } private area(): any { return this.fb.group({ name: ['', [Validators.required]], latLong: ['', [Validators.required]], details: ['', [Validators.required]] }); } public ngOnInit(): void { this.areasForm = this.fb.group({ name: ['', [Validators.required]], areas: this.fb.array([this.area()]) }); } } 

and my template file

<form [formGroup]="areasForm" (ngSubmit)="onSubmit(areasForm.values)"> <md-input-container> <input mdInput placeholder="Location Name" type="text" formControlName="name" required> <md-error *ngIf="areasForm.get('name').hasError('required')">Please enter the locationName</md-error> </md-input-container> <md-grid-list cols="1" [formArrayName]="areas"> <md-grid-tile formGroupName="i" colspan="1" rowHeight="62px" *ngFor="let area of areasForm.controls.areas.controls; let i = index "> <md-grid-list cols="3" rowHeight="60px"> <md-grid-tile colspan="1"> <md-input-container> <input mdInput placeholder="Area Name" type="text" formControlName="name" required> <md-error *ngIf="areasForm.get('areas').controls[i].name.hasError('required')">Please enter the area name</md-error> </md-input-container> </md-grid-tile> <md-grid-tile colspan="1"> <md-input-container> <input mdInput placeholder="details" type="text" formControlName="details" required> <md-error *ngIf="areasForm.get('areas').controls[i].name.hasError('required')">Please enter the locationName</md-error> </md-input-container> </md-grid-tile> <md-grid-tile colspan="1"> <button md-fab (click)="remove(i)"><md-icon>subtract</md-icon>Remove Area</button> </md-grid-tile> </md-grid-list> </md-grid-tile> </md-grid-list> <button type="submit" [disabled]="areasForm.invalid" md-raised-button color="primary">Submit</button> </form> 

11 Answers

Remove the brackets from

[formArrayName]="areas" 

and use only

formArrayName="areas" 

This, because with [ ] you are trying to bind a variable, which this is not. Also notice your submit, it should be:

(ngSubmit)="onSubmit(areasForm.value)" 

instead of areasForm.values.

4

In my case I solved the issue by putting the name of the formControl in double and sinlge quotes so that it is interpreted as a string:

[formControlName]="'familyName'" 

similar to below:

formControlName="familyName" 
1

The problem for me was that I had

[formControlName]="" 

Instead of

formControlName="" 
1

Instead of

formGroupName="i" 

You must use:

[formGroupName]="i" 

Tips:

Since you're looping over the controls, you've already the variable area, so you can replace this:

*ngIf="areasForm.get('areas').controls[i].name.hasError('required')" 

by:

*ngIf="area.hasError('required', 'name')" 
1

For me, I was trying to add [formGroupName]="i" and/or formControlName and forgetting to specify the parent formArrayName. Pay attention to your form group tree.

2

This was happening for me because I had fromArrayName instead of formArrayName somewhere 😑

0

So, I had this code:

<div *ngIf="contentData"> <button mat-stroked-button [disableRipple]="true" (click)="openSelect()" [ngClass]="{'only-icon': !contentData?.buttonText?.length}"> <i *ngIf="contentData.iconClassInfo"></i> <span *ngIf="contentData.buttonText">{{contentData.buttonText}}</span> </button> <mat-select [formControl]="theFormControl" #buttonSelect (selectionChange)="onSelect(buttonSelect.selected)" (click)="$event.stopPropagation();"> <mat-option *ngFor="let option of options" [ngClass]="{'selected-option': buttonSelect.selected?.value === option[contentData.optionsStructure.valName]}" [disabled]="buttonSelect.selected?.value === option[contentData.optionsStructure.valName] && contentData.optionSelectedWillDisable" [value]="option[contentData.optionsStructure.valName]"> {{option[contentData.optionsStructure.keyName]}} </mat-option> </mat-select> </div> 

Here I was using standalone formControl, and I was getting the error we are talking about, which made no sense for me, since I wasn't working with formgroups or formarrays... it only disappeared when I added the *ngIf to the select it self, so is not being used before it actually exists. That's what solved the issue in my case.

<mat-select [formControl]="theFormControl" #buttonSelect (selectionChange)="onSelect(buttonSelect.selected)" (click)="$event.stopPropagation();" *ngIf="theFormControl"> <mat-option *ngFor="let option of options" [ngClass]="{'selected-option': buttonSelect.selected?.value === option[contentData.optionsStructure.valName]}" [disabled]="buttonSelect.selected?.value === option[contentData.optionsStructure.valName] && contentData.optionSelectedWillDisable" [value]="option[contentData.optionsStructure.valName]"> {{option[contentData.optionsStructure.keyName]}} </mat-option> </mat-select> 
1

This happened to me because I left a formControlName empty (formControlName=""). Since I didn't need that extra form control, I deleted it and the error was resolved.

Only WinMerge made me find it (by comparison with a version that works). I had a case problem on formGroupName. Brackets around this word can lead to the same problem.

I had accidentally entered the control name when creating the formGroup:

getFormGroup(dataItem: any): FormGroup { return new FormGroup({ 'Id': new FormControl(dataItem != null ? dataItem.Id : ''), 'PsDepartmentId': new FormControl(dataItem != null ? dataItem.DepartmentId : '', Validators.required), //Accidentally used 'DepartmentId' on this line 'IsActive': new FormControl(dataItem != null ? dataItem.IsActive : true) }); } 

Then it failed in the html when I did

 <kendo-dropdownlist [data]="psDepartments" textField="ConCatedName" valueField="Id" [formControl]="formGroup.get('DepartmentId')" [valuePrimitive]="true"> </kendo-dropdownlist> 

For me, the issue was I was missing the field name in the form builder:

 return this.fb.group({ name: ['', [Validators.required]], latLong: ['', [Validators.required]], details: ['', [Validators.required]], // missing field name! }); 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy