Reputation: 3211
I'm trying to build a custom form validation method in angular 2. The problem is that when I run the project I'm getting the following error:
Property 'controls' does not exist on type 'AbstractControl'.
But if I ignore it and continue using my app I see that the validate function works as planed.
Anyone else face this issue ? Why I'm getting this errors? I'm gassing that is somehow related to typescript rather then to the angular itself (I'm using typescript 2.0.3).
This is my code:
imports:
import {Injectable} from '@angular/core';
import {RegexService} from "./regex.service";
import {FormControl, ValidatorFn} from "@angular/forms";
The custom validate function:
requireGroupMinAmount(minPossibleAmount): ValidatorFn {
return (control: FormControl): string[]=> {
let requireCounter = 0;
if (!control)
return null;
controlsLoop:for (let formOptionKey in control.controls) {
for (let formOptionValue in control.controls[formOptionKey].controls) {
if (control.controls[formOptionKey].controls[formOptionValue].value)
requireCounter++;
if (requireCounter >= minPossibleAmount)
break controlsLoop;
}
}
return requireCounter >= minPossibleAmount
? null
: ["Please fill at least " + minPossibleAmount + " fields"];
}
}
Thanks in advance.
Upvotes: 2
Views: 808
Reputation: 123861
The child collection/dictionary controls
is defined on derived classes FormGroup
and FormArray
. So, if we want to iterate FormGroup
(which controls
are of type dictionary), we would need to do this check:
if (control instanceof FormGroup)
{
controlsLoop:for (let formOptionKey in control.controls) {
...
}
}
no compiler (and even runtime) will properly iterate only if that abstract control is FormGroup
instance
Also, we have to be sure, that coming value is AbstractControl
requireGroupMinAmount(minPossibleAmount): ValidatorFn {
//return (control: FormControl): string[]=> {
return (control: AbstractControl): string[]=> {
and not the subtype FormControl. Only abstract base could be properly check if is it of some of its subtypes (e.g. FormArray)
There is adjusted code snippet (check in playground):
requireGroupMinAmount(minPossibleAmount): validatorFn{
return (control: AbstractControl): string[] => {
let requireCounter = 0;
if (!control)
return null;
if (control instanceof FormGroup) {
controlsLoop: for (let formOptionKey in control.controls) {
var childControl: AbstractControl = control.controls[formOptionKey];
if (childControl instanceof FormGroup) {
for (let formOptionValue in childControl.controls) {
if (childControl.controls[formOptionValue].value)
requireCounter++;
if (requireCounter >= minPossibleAmount)
break controlsLoop;
}
}
}
}
return requireCounter >= minPossibleAmount
? null
: ["Please fill at least " + minPossibleAmount + " fields"];
}
}
Upvotes: 2