Angular - Validador de unicidad en FormArray
Creé un validador personalizado para validar la unicidad en miFormArray
. Quiero mostrar un error cuando los valores específicos están en la matriz.
El problema es que no funciona como se esperaba.
Comportamiento real:
Pasos para reproducir:
Agregue 3 "entradas" - dirección;Llene la entrada 1;Rellene la entrada 2 con un valor diferente;Rellene la entrada 3 con el mismo valor de la entrada 1; (no aparecen errores, ni en la entrada 1 ni en la entrada 3)Comportamiento esperado:
Si los mismos valores aparecen en "grupos X", sus entradas específicas deben mostrar el error.
En el caso descrito anteriormente, los errores deberían aparecer en las entradas 1 y 3.
Suponiendo que tengo 4 entradas:
valor: apilarvalor: desbordamientovalor: apilarvalor: desbordamientoLas 4 entradas deben mostrar un error, porque todas son duplicadas.
static uniqueBy = (field: string, caseSensitive = true): ValidatorFn => {
return (formArray: FormArray): { [key: string]: boolean } => {
const controls = formArray.controls.filter(formGroup => {
return isPresent(formGroup.get(field).value);
});
const uniqueObj = { uniqueBy: true };
let found = false;
if (controls.length > 1) {
for (let i = 0; i < controls.length; i++) {
const formGroup = controls[i];
const mainControl = formGroup.get(field);
const val = mainControl.value;
const mainValue = caseSensitive ? val.toLowerCase() : val;
controls.forEach((group, index) => {
if (i === index) {
// Same group
return;
}
const currControl = group.get(field);
const tempValue = currControl.value;
const currValue = caseSensitive ? tempValue.toLowerCase() : tempValue;
let newErrors;
if ( mainValue === currValue) {
if (isBlank(currControl.errors)) {
newErrors = uniqueObj;
} else {
newErrors = Object.assign(currControl.errors, uniqueObj);
}
found = true;
} else {
newErrors = currControl.errors;
if (isPresent(newErrors)) {
// delete uniqueBy error
delete newErrors['uniqueBy'];
if (isBlank(newErrors)) {
// {} to undefined/null
newErrors = null;
}
}
}
// Add specific errors based on condition
currControl.setErrors(newErrors);
});
}
if (found) {
// Set errors to whole formArray
return uniqueObj;
}
}
// Clean errors
return null;
};
}
Puede comprobar aquíMANIFESTACIÓN.