Evan Scott
Evan Scott

Reputation: 79

Accessing Nested Controls of Angular Forms

I'm upgrading an application from Angular 2 to 7, and it looks like most of my forms have broken. I have multiple instances where I receive the following error:

Property 'controls' does not exist on type 'AbstractControl'

In this particular instance, I have a block that appears to looping through and validating form arrays.

for (let i = 0, len = this.form.controls[control].controls.length; i < len; i++) {

  this.form.controls[control].controls[i].controls.ConditionTypeId.setValidators(Validators.required);
  this.form.controls[control].controls[i].controls.ConditionTypeId.updateValueAndValidity();
  this.form.controls[control].controls[i].controls.ToBeCompletedDate.setValidators(Validators.required);
  this.form.controls[control].controls[i].controls.ToBeCompletedDate.updateValueAndValidity();
}

Has there been a major change in how nested forms/form arrays work since Angular 2, and if so, what would be the most efficient way for me to refactor any code that deals with nested forms in this manner?

Upvotes: 3

Views: 151

Answers (1)

Frederick
Frederick

Reputation: 872

I'm not sure when the change occurred because I didn't get serious with Angular until v4. But I believe your issue is just a bit stricter typing or restructuring of the form classes. AbstractControl is a generic abstract class for these form classes. The FormArray class extends that and adds that controls property that you're looking for. But FormGroup.controls[...] just returns the generic AbstractControl. So, you have to cast it to a FormArray before trying to get the controls from it:

(this.form.controls[control] as FormArray).controls[i].controls...

The more common pattern is to create a getter for the specific arrays, but a simple function in the backing ts file might be more appropriate in your case:

getFormArray(controlName) {
  return this.myForm.get(controlName) as FormArray;
}

Upvotes: 2

Related Questions