Property 'controls' does not exist on type 'AbstractControl' Angular 4
Solution 1
Based on @Günter Zöchbauer comments , first i changed
myForm.controls['addresses']
to myForm.get('addresses')
in both html and typescript
and then based on @yuruzi comment
changed myForm.get('addresses').controls
to myForm.get('addresses')['controls']
Its working fine now. Thanks @gunter & yuruzi
Solution 2
You can fix it easily though. Outsource the "get the controls" logic into a method of your component code (the .ts
file):
getControls() {
return (this.recipeForm.get('controlName') as FormArray).controls;
}
In the template, you can then use:
*ngFor="let ingredientCtrl of getControls(); let i = index"
This adjustment is required due to the way TS works and Angular parses your templates (it doesn't understand TS there).
Solution 3
As an update to @sunny kashyap solution, I would write it this way:
getControls() {
return (this.recipeForm.get('controlName') as FormArray).controls;
}
Solution 4
Change myForm.get('addresses').controls
to myForm.get('addresses').value
will also fix the issue.
Solution 5
for validation errors use...
<span *ngIf="f.YOUR_FORM_KEY.controls.YOUR_FORM_KEY.errors?.YOUR_FORM_VALIDATION">YOUR_FORM_KEY is YOUR_FORM_VALIDATION</span>
eg.
<span *ngIf="f.name.controls.name.errors?.required">Name is required</span>
ts file
get f(): any {
return this.userForm.controls;
}
Related videos on Youtube
Comments
-
Munna Babu over 3 years
I am trying a nested reactive form in Angular 4. It is working fine but when I try to build AOT it's throwing the error
'controls' does not exist on type 'AbstractControl'
I googled and tried few things but no luck. Could anyone tell me how to fix this issue?
<div [formGroup]="myForm"> <div formArrayName="addresses"> <div *ngFor="let address of myForm.get('addresses').controls; let i=index" class="panel panel-default"> <span *ngIf="myForm.get('addresses').length > 1" (click)="removeAddress(i)">Remove</span> <div [formGroupName]="i"> <mat-form-field> <input matInput formControlName="city" placeholder="city" value=""> </mat-form-field> </div> </div> </div> <a (click)="addAddress()" style="cursor: default"> Add +</a> </div>
typescript code below
constructor(private _fb: FormBuilder) { } ngOnInit() { this.myForm = this._fb.group({ addresses: this._fb.array([ this.initAddress(), ]) }); } initAddress() { return this._fb.group({ city: [''] }); } addAddress() { const control = <FormArray>this.myForm.get('addresses'); control.push(this.initAddress()); } removeAddress(i: number) { const control = <FormArray>this.myForm.get('addresses'); control.removeAt(i); }
-
Günter Zöchbauer over 6 yearsI think the preferred way is
myForm.get('addresses')
-
Munna Babu over 6 years@GünterZöchbauer do we need to use this in HTML ngFor or in the Typescript ?
-
Günter Zöchbauer over 6 yearsShould work in both if
myForm
is anAbstractControl
-
Munna Babu over 6 years@GünterZöchbauer updated code in the question as per ur suggestion, its working fine but AOT throw same error :( any idea ? pls chk code
-
Günter Zöchbauer over 6 yearsThen you probably changed it on the wrong place. It's quite unlikely that
get()
throws an error thatcontrols()
doesn't exist. -
yurzui over 6 yearscreate getter like
get addressesControls() { return (<FormArray>this.myForm.get('addresses')).controls; }
or just use the followingmyForm.get('addresses')['controls']
-
Munna Babu over 6 years@yurzui Thanks just update myForm.get('addresses')['controls'] in HTML , its working fine now
-
HD.. over 6 yearshow this thing will itterate may I know Munna rentalPricingForm.controls.pricingBundle.controls[i].controls.packageName.errors
-
-
Munna Babu over 6 yearsThanks. But It doesn't fix issue.
-
Munna Babu over 6 yearsYes @mohammed, pls chk the updated code in question
-
Mohamed Ali RACHID over 6 yearscan you please try this
let address of myForm.controls.addresses.controls
instead oflet address of myForm.get('addresses').controls
-
Victor Reyes almost 5 yearsMaybe on later angular versions you have to use
return (this.recipeForm.get('controlName') as FormArray).controls;
-
Rafael L R almost 5 yearsMy case: form.get('user')['controls'].profile. its ok tnks
-
Kelvin Cayman about 4 yearsThis wrked for me seamlessly. Thanks Man! In the tempate
myForm.get('addresses')['controls']
In the tsconst control = this.myForm.controls.addresses as FormArray
-
Majesty over 3 yearsKinda woodoo magic, it must be working without array notation....