export interface AllValidationErrors {
controlName: string;
errorName: string;
errorValue: any;
}
export function getFormValidationErrors(control: AbstractControl | FormGroup | FormArray, errors: AllValidationErrors[] = [], name: string = null): AllValidationErrors[] {
if (control instanceof FormControl) {
if (control.errors !== null) {
return Object.entries<{ [key: string]: string }>(control.errors)
.reduce<AllValidationErrors[]>(
(acc, [errorKey, errorValue]) =>
[...acc, {controlName: name, errorName: errorKey, errorValue: errorValue}], errors)
}
} else if(control instanceof FormGroup) {
return Object.entries(control.controls).reduce<AllValidationErrors[]>((acc, [name, control]) => getFormValidationErrors(control, acc, name), errors);
} else if(control instanceof FormArray) {
return control.controls.reduce<AllValidationErrors[]>((acc, control, index) => getFormValidationErrors(control, acc, `${name}[${index}]`), errors);
}
}
Automation
it('Should collect all the form error into single list', () => {
const formGroup = new FormGroup({
name: new FormControl(null, [Validators.required]),
address: new FormGroup({
street: new FormControl(null, [Validators.required]),
}),
list: new FormArray([
new FormGroup({
test: new FormControl(null, [Validators.required]),
innerList: new FormArray([
new FormGroup({
test3: new FormControl(null, [Validators.required])
})
]),
innerList2: new FormArray([
new FormControl(null, [Validators.required]),
]),
})
]),
list2: new FormArray([
new FormControl(null, [Validators.required])
]),
});
const result: AllValidationErrors[] = getFormValidationErrors(formGroup);
console.table(result)
const expected: AllValidationErrors[] = [
{ controlName: 'name', errorName: 'required', errorValue: true },
{ controlName: 'street', errorName: 'required', errorValue: true },
{ controlName: 'test', errorName: 'required', errorValue: true },
{ controlName: 'list2[0]', errorName: 'required', errorValue: true }
];
expect(result).toEqual(expected);
});
Console output