Angular Type 'AbstractControl' is missing the following properties from type 'FormGroup': controls
Asked Answered
M

2

11

I working on Angular FormArray, therefore I working on this tutorial: https://www.youtube.com/watch?v=aOQ1xFC3amw Unfortunately I can’t apply the tutorial. I got an error in my HTML part.

I use Angular 11

This is my HTML showing the error message:

    <div [formGroup]="myForm">
         <ng-container formArrayName="demoTypes">

                <ng-container *ngFor="let demoForm of demoFormArray.controls">

                    <div [formGroup]="demoForm"><!--formGroup is as error underlined-->
                       
                    </div>

                </ng-container>

         </ng-container>
    </div>

The error message is:

Type 'AbstractControl' is missing the following properties from type 'FormGroup': controls, registerControl, addControl, removeControl, and 3 more.

This is my TypeScript class:


    export class DemoComponent implements OnInit {

        myForm!: FormGroup;

        constructor(private formBuilder: FormBuilder) { }

        ngOnInit(): void {
            this.createForm();
        }

        createForm() {
            this.myForm = this.formBuilder.group({
                demoTypes: new FormArray([]),
            });

            this.addDemoTypes();
        }

        get demoFormArray() {
            return this.myForm.controls["demoTypes"] as FormArray;
        }

        addDemoTypes(): void {
            const demoControl = this.formBuilder.group({
                isChecked: new FormControl(true),
                demoFormControlName: new FormControl("This is the first one"),
            });
            this.demoFormArray.push(demoControl);
        }
    }

What’s the problem here?

[EDIT] Setting "strictTemplates": false in tsconfig.json fixed my problem. But is this a good idea?

"angularCompilerOptions": {
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": false
}
Mccammon answered 3/5, 2021 at 8:46 Comment(0)
T
12

You can use formGroupName instead

  <ng-container *ngFor="let demoForm of demoFormArray.controls; let i = index">

    <div [formGroupName]="i">
                    
    </div>
</ng-container>

We will not encounter the typescript error as we are binding to a number

Disabling strictTemplates?

Don't. With enabled strictTemplates you are more likely to catch problems that could otherwise have been overseen. I think burrying the head in the sand never solves the problem. You may not see the danger but the danger is still there

Tetanize answered 3/5, 2021 at 9:15 Comment(3)
Thank's a lot! Can I assume that the author of the tutorial worked without strict templates? I'll go on with strict templates and fix my code.Mccammon
They must have been, but its safer to go with strict templates, after all there is no harm in using it but not using it is likely to cause harm...Tetanize
I upgraded my project from I think 8 to 14 and it is simply killing me. Between that and having to initialize all teh variables... i get it, just has taken many hours to have a 20 component app to get back to compiling... ugh.Ardussi
Z
6

For people trying to figure out how to handle this when you want to continue to use the value from the for loop in your template, you can define a getter to return the controls array in order to cast it to FormGroup.

Add getter to typescript class:

public get demoFormArrayControls() {
    return (this.myForm.controls["demoTypes"] as FormArray).controls as FormGroup[];
}

Now all you have to change in the html is the collection of your loop:

<div [formGroup]="myForm">
    <ng-container formArrayName="demoTypes">
        <ng-container *ngFor="let demoForm of demoFormArrayControls">
            <div [formGroup]="demoForm">

            </div>
        </ng-container>
    </ng-container>
</div>
Zeba answered 6/9, 2022 at 23:9 Comment(1)
in typed forms and strictTemplates = true this works thank youEnthuse

© 2022 - 2024 — McMap. All rights reserved.