typescript - Hae kaikki validointivirheet Angular 2 FormGroupista


Annettua tätä koodia:

this.form = this.formBuilder.group({
  email: ['', [Validators.required, EmailValidator.isValid]],
  hasAcceptedTerms: [false, Validators.pattern('true')]
});

Kuinka voin saada kaikki validointivirheet kohteesta this.form?

Kirjoitan yksikkötestejä ja haluan sisällyttää varsinaiset validointivirheet assert-viestiin.

Vastaus #1

Tapasin saman ongelman ja kaikkien validointivirheiden löytämiseksi ja näyttämiseksi kirjoitin tämän metodin:

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]);
      });
    }
  });
}

Lomakkeen nimi productForm tulisi muuttaa omaksi lomake-instanssin nimeksi.

Se toimii näin: saamme kaikki kontrollimme lomakkeesta muodossa {[p: string]: AbstractControl} ja käymme läpi jokaisen virheavaimen saadaksemme virheen yksityiskohdat. Se ohittaa null virhearvot.

Sitä voidaan myös muuttaa näyttämään validointivirheitä mallinäkymässä, vaihda vain console.log(..) siihen, mitä tarvitset.

Vastaus #2

Tämä on ratkaisu, jossa FormGroup sisällä tukee ( kuten täällä )

Testattu versiolla: Angular 4.3.6

hanki-lomakkeen-tarkistusvirheet.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;
}

Esimerkin käyttö:

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;
}

Vastaus #3

Rekursiivinen tapa hakea kaikki virheet Angular-lomakkeesta, lomakerakenteen luomisen jälkeen ei ole olemassa tapaa hakea kaikkia virheitä lomakkeesta. Tämä on erittäin hyödyllistä virheiden jäljittämiseen, mutta myös virheiden visualisointiin.

Testattu Angular 9:lle

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;
    }
}

Vastaus #4

Tässä on toinen muunnelma, joka kerää virheet rekursiivisesti eikä riipu mistään ulkoisesta kirjastosta, kuten lodash (vain ES6):

function isFormGroup(control: AbstractControl): control is FormGroup {
  return !!(<FormGroup>control).controls;
}

function collectErrors(control: AbstractControl): any | null {
  if (isFormGroup(control)) {
    return Object.entries(control.controls)
      .reduce(
        (acc, [key, childControl]) => {
          const childErrors = collectErrors(childControl);
          if (childErrors) {
            acc = {...acc, [key]: childErrors};
          }
          return acc;
        },
        null
      );
  } else {
    return control.errors;
  }
}

Aiheeseen liittyviä artikkeleita