I want to get count of form fields.
Total count of fields and valid and invalid form fields. So I try with this function but getting this below error.
Error I am getting below :
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'AbstractControl<any, any>'.
No index signature with a parameter of type 'string' was found on type 'AbstractControl<any, any>'
const firstFormGroup = this.allFormGroup.controls['firstFormGroup'];
const invalidArr = [];
const validArr = [];
for (const name in firstFormGroup) {
if (firstFormGroup[name].status === 'INVALID') { // I am getting error on this line
invalidArr.push(name);
} else {
validArr.push(name);
}
}
console.log(`valid count : ${validArr.length}`)
console.log(`invalid count : ${invalidArr.length}`)
CodePudding user response:
There are a few issues with the code above. The first thing is that it is not iterating through controls but rather through the attributes of the returned object.
The first thing to do is to let TypeScript know the type you expect from the first assignment:
const firstFormGroup = this.contactForm.controls['firstFormGroup'] as FormGroup;
then later on instead of iterating through the attributes of the object iterate through the controls (the intended behaviour):
for (const name in firstFormGroup.controls)
Then to access the controls by name use the method that lets you query controls by name instead of using an index
let item = firstFormGroup.get(name);
item can be null so do the appropriate checks now. In readable code this gets you:
const firstFormGroup = this.contactForm.controls['firstFormGroup'] as FormGroup;
const invalidArr = [];
const validArr = [];
for (const name in firstFormGroup.controls) {
let item = firstFormGroup.get(name);
if (item !== null) {
if (item.status === 'INVALID') {
invalidArr.push(name);
} else {
validArr.push(name);
}
}
}
console.log(`valid count : ${validArr.length}`)
console.log(`invalid count : ${invalidArr.length}`)
CodePudding user response:
Longer version of my comment.
When objects have no index signature like [key: string]: T
you can't use strings to index it. You can use the original Type and the keyof
operator.
firstFormGroup[name as keyof AbstractControl].status === 'INVALID'
This way you make sure that name isn't just a string but actually a key from AbstractControl that can be used as to index itself.
If you aren't sure what the type of an object is, or it has been dynamically typed you can use keyof typeof T
const firstFormGroup = this.allFormGroup.controls['firstFormGroup']; // this is your object
[...]
firstFormGroup[name as keyof typeof firstFormGroup].status === 'INVALID'
[...]
This way you don't have to import AbstractControl and this also works on pretty much every type of object you may encounter.