How to find the invalid controls in Angular(v2 onwards) reactive form
I have a reactive form in Angular like below:
this.AddCustomerForm = this.formBuilder.group({
Firstname: ['', Validators.required],
Lastname: ['', Validators.required],
Email: ['', Validators.required, Validators.pattern(this.EMAIL_REGEX)],
Picture: [''],
Username: ['', Validators.required],
Password: ['', Validators.required],
Address: ['', Validators.required],
Postcode: ['', Validators.required],
City: ['', Validators.required],
Country: ['', Validators.required]
});
createCustomer(currentCustomer: Customer)
{
if (!this.AddCustomerForm.valid)
{
//some app logic
}
}
this.AddCustomerForm.valid returns false, but everything looks good.
I have tried to find with checking the status property in the controls collection. But I wonder if there is a way to find the invalid ones and display to the user?
You can simply iterate over every control and check the status:
public findInvalidControls() {
const invalid = [];
const controls = this.AddCustomerForm.controls;
for (const name in controls) {
if (controls[name].invalid) {
invalid.push(name);
}
}
return invalid;
}
An invalid Angular control has the CSS class named 'ng-invalid'.
Under DevTools in Chrome, select Console tab.
In console prompt run the following command in order to get the invalid Angular controls that bear the CSS class 'ng-invalid'
document.getElementsByClassName('ng-invalid')
The output should be similar to this:
In this case, the underlined text is for the form control listen-address
and the encircled text: .ng-invalid
indicates that the control is invalid.
Note: Tested in chrome
I just battled this issue: Every form field is valid, but still the form itself is invalid.
Turns out that I had set 'Validator.required' on a FormArray where controls are added/removed dynamically. So even if the FormArray was empty, it was still required and therefore the form was always invalid, even if every visible control was correctly filled.
I didn't find the invalid part of the form, because my 'findInvalidControls' function only checked FormControl's and not FormGroup/FormArray. So I updated it a bit:
/*
Returns an array of invalid control/group names, or a zero-length array if
no invalid controls/groups where found
*/
public findInvalidControlsRecursive(formToInvestigate:FormGroup|FormArray):string[] {
var invalidControls:string[] = [];
let recursiveFunc = (form:FormGroup|FormArray) => {
Object.keys(form.controls).forEach(field => {
const control = form.get(field);
if (control.invalid) invalidControls.push(field);
if (control instanceof FormGroup) {
recursiveFunc(control);
} else if (control instanceof FormArray) {
recursiveFunc(control);
}
});
}
recursiveFunc(formToInvestigate);
return invalidControls;
}
Now, in angular 9, you can use the markAllAsTouched() method to show the invalid controls validators:
this.AddCustomerForm.markAllAsTouched();