Cannot find control with unspecified name attribute on formArrays
Asked Answered
B

17

129

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 class="areas-form" [formGroup]="areasForm" (ngSubmit)="onSubmit(areasForm.values)">
    <md-input-container class="full-width">
        <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 class="full-width">
                        <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 class="full-width">
                        <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>
Bust answered 16/4, 2017 at 13:21 Comment(0)
Y
179

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.

Yaekoyael answered 16/4, 2017 at 16:12 Comment(5)
Is your plunkr broken?Neukam
and yet [FormGroup]="areasForm" is correct? Angular is really kicking me in the pants....Insure
The curly brackets were the problem in my case with the formGroupNameRetaliation
@Insure late to comment... [formGroup]="areasForm" is correct because areasForm is a variable in your component TS, whereas areas is not. It is property of the areasForm :)Yaekoyael
I had this error pointing to row "106" in my template. It turned out that the formControl before that line was misspelled! So this error is saying that error is at row X, when it is actually before that. Oh btw, upgrade to 14+ if you can. It has typed forms!Lustihood
C
27

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"
Conflux answered 6/6, 2017 at 14:40 Comment(1)
Thank you for the explanation. I kept seeing the formControlName wrapped in single quotes but the difference between passing it as a string vs the formControl object didn't click until seeing this.Mystic
P
11

The problem for me was that I had

[formControlName]=""

Instead of

formControlName=""
Paracelsus answered 20/5, 2017 at 8:8 Comment(1)
I needed to change from [formControl] to formControlNameSamarskite
C
7

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')"
Catalonia answered 16/4, 2017 at 13:57 Comment(1)
Thanks, that seemed to be part of the problem but the answer above solved my issue.Bust
E
7

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.

Eckel answered 15/10, 2018 at 14:9 Comment(2)
I was using both as well. Remember to put the formArrayName on a DOM-element higher up in the hierarchy than [formGroupName]="i" (e.g. on the loop element: <div *ngFor=let ctrl of formArrayCtrl; let i = index"><div [formGroupName]="i"></div></div>)Unobtrusive
Pay attention to form group tree helped me.Organzine
C
4

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

Correll answered 14/6, 2018 at 5:32 Comment(0)
H
3

So, I had this code:

<div class="dropdown-select-wrapper" *ngIf="contentData">
    <button mat-stroked-button [disableRipple]="true" class="mat-button" (click)="openSelect()" [ngClass]="{'only-icon': !contentData?.buttonText?.length}">
      <i *ngIf="contentData.iconClassInfo" class="dropdown-icon {{contentData.iconClassInfo.name}}"></i>
      <span class="button-text" *ngIf="contentData.buttonText">{{contentData.buttonText}}</span>
    </button>
    <mat-select class="small-dropdown-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 class="small-dropdown-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>
Herculie answered 5/3, 2020 at 17:55 Comment(1)
I had the problem when a host modal component was dismissed. I had to use ngIf to check whether the control was still available when closing my dialog.Pet
S
1

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!
  });
Szabo answered 9/9, 2021 at 19:13 Comment(0)
T
1

In my case, I forgot to initialize the form in ngOnInit() when using [formControl]="customForm".

Tighten answered 28/8, 2023 at 7:46 Comment(0)
C
1

In Angular 17, I encountered an issue where the initialization was delayed, causing the [formControl] to temporarily bind to null. To address this, I used *ngIf='!!employerForm' to ensure that the employerForm was initialized before rendering the template. This approach prevented the form from displaying with uninitialized controls.

    <input  
          *ngIf='!!employerForm'
          type="text"
          [formControl]="employerForm?.get('role_title')"
          [attr.data-test-id]="'application_detail_job_title_txt'" />
Conquer answered 13/6, 2024 at 7:22 Comment(0)
H
0

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.

Hairston answered 2/12, 2019 at 20:43 Comment(0)
L
0

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.

Libelous answered 6/2, 2021 at 12:5 Comment(0)
S
0

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 id="ps-dpts-dropdown" [data]="psDepartments" textField="ConCatedName" valueField="Id"
          [formControl]="formGroup.get('DepartmentId')" [valuePrimitive]="true">                  
          </kendo-dropdownlist>
Szabo answered 16/4, 2021 at 21:27 Comment(0)
M
0

Angular 13! formControlName should not empty.

formControlName=""
Miscount answered 13/10, 2022 at 18:34 Comment(0)
P
0

It was because formControlName='' was empty.

Pastose answered 4/1, 2023 at 20:12 Comment(0)
F
0

Change [formControl] to formControlName and simple give the name. formControlName="name". Main thing to notice it should be under proper formGroupName or formArrayName.

Fishbein answered 19/3, 2024 at 10:45 Comment(0)
N
0

For me, I declared a input name with formControl which should be avoided.

Renaming the formControl to another name like formCtrl removed the error

Northey answered 6/5, 2024 at 8:6 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.