Get all validation errors from Angular 2 FormGroup

This is solution with FormGroup inside supports ( like here )

Tested on: Angular 4.3.6

get-form-validation-errors.ts

import { AbstractControl, FormGroup, ValidationErrors } from '@angular/forms';

export interface AllValidationErrors {
  control_name: string;
  error_name: string;
  error_value: any;
}

export interface FormGroupControls {
  [key: string]: AbstractControl;
}

export function getFormValidationErrors(controls: FormGroupControls): AllValidationErrors[] {
  let errors: AllValidationErrors[] = [];
  Object.keys(controls).forEach(key => {
    const control = controls[ key ];
    if (control instanceof FormGroup) {
      errors = errors.concat(getFormValidationErrors(control.controls));
    }
    const controlErrors: ValidationErrors = controls[ key ].errors;
    if (controlErrors !== null) {
      Object.keys(controlErrors).forEach(keyError => {
        errors.push({
          control_name: key,
          error_name: keyError,
          error_value: controlErrors[ keyError ]
        });
      });
    }
  });
  return errors;
}

Using example:

if (!this.formValid()) {
  const error: AllValidationErrors = getFormValidationErrors(this.regForm.controls).shift();
  if (error) {
    let text;
    switch (error.error_name) {
      case 'required': text = `${error.control_name} is required!`; break;
      case 'pattern': text = `${error.control_name} has wrong pattern!`; break;
      case 'email': text = `${error.control_name} has wrong email format!`; break;
      case 'minlength': text = `${error.control_name} has wrong length! Required length: ${error.error_value.requiredLength}`; break;
      case 'areEqual': text = `${error.control_name} must be equal!`; break;
      default: text = `${error.control_name}: ${error.error_name}: ${error.error_value}`;
    }
    this.error = text;
  }
  return;
}

I met the same problem and for finding all validation errors and displaying them, I wrote this method:

getFormValidationErrors() {
  Object.keys(this.productForm.controls).forEach(key => {
    const controlErrors: ValidationErrors = this.productForm.get(key).errors;
    if (controlErrors != null) {
      Object.keys(controlErrors).forEach(keyError => {
       console.log('Key control: ' + key + ', keyError: ' + keyError + ', err value: ', controlErrors[keyError]);
      });
    }
  });
}

Form name productForm should be changed to your form instance name.

It works in this way: we get all our controls from the form in format {[p: string]: AbstractControl} and iterate by each error key, to get details of error. It skips null error values.

It also can be changed for displaying validation errors on the template view, just replace console.log(..) to what you need.


Recursive way to retrieve all the errors from an Angular form, after creating any kind of formulary structure there's no way to retrieve all the errors from the form. This is very useful for debugging purposes but also for plotting those errors.

Tested for Angular 9

getFormErrors(form: AbstractControl) {
    if (form instanceof FormControl) {
        // Return FormControl errors or null
        return form.errors ?? null;
    }
    if (form instanceof FormGroup) {
        const groupErrors = form.errors;
        // Form group can contain errors itself, in that case add'em
        const formErrors = groupErrors ? {groupErrors} : {};
        Object.keys(form.controls).forEach(key => {
            // Recursive call of the FormGroup fields
            const error = this.getFormErrors(form.get(key));
            if (error !== null) {
                // Only add error if not null
                formErrors[key] = error;
            }
        });
        // Return FormGroup errors or null
        return Object.keys(formErrors).length > 0 ? formErrors : null;
    }
}