typescript - Angular 2 FormGroup'ten tüm doğrulama hatalarını al


Verilen bu kod:

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

this.form'den tüm doğrulama hatalarını nasıl alabilirim?

Birim testleri yazıyorum ve assert mesajına gerçek doğrulama hatalarını dahil etmek istiyorum.

Cevap #1

Ben de aynı sorunla karşılaştım ve tüm doğrulama hatalarını bulup göstermek için bu yöntemi yazdım:

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 adı productForm, form örneği adınızla değiştirilmelidir.

Şu şekilde çalışır: Tüm kontrollerimizi formdan {[p: string]: AbstractControl} formatında alırız ve hatanın detaylarını almak için her hata anahtarı üzerinde iterasyon yaparız. null hata değerlerini atlar.

Ayrıca, şablon görünümünde doğrulama hatalarını görüntülemek için değiştirilebilir, sadece console.log(..) yerine ihtiyacınız olanı koyun.

Cevap #2

Bu, içinde FormGroup bulunan çözümü destekler ( burası gibi )

Test Edildi: 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;
}

Örnek kullanımı:

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

Cevap #3

Angular formundan tüm hataları özyinelemeli şekilde alma yolu, her türlü form yapısı oluşturulduktan sonra formdan tüm hataları almak için bir yol yoktur. Bu, hata ayıklama amaçları için çok kullanışlıdır ama aynı zamanda bu hataları görselleştirmek için de faydalıdır.

Angular 9 için test edildi

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

Cevap #4

Bu, hataları özyinelemeli olarak toplayan ve lodash gibi herhangi bir dış kütüphaneye bağımlı olmayan başka bir varyanttır (sadece 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;
  }
}

İlgili makaleler