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