I have a form group to manage time of day as follows:
time: new FormGroup({
date: new FormControl(new Date()),
startTime: new FormControl(null),
startTimeMeridian: new FormControl(MERIDIAN.PM),
stopTime: new FormControl(null),
stopTimeMeridian: new FormControl(MERIDIAN.PM)
}, [MyCustomValidators.futureDateTime()]),
Inside my futureDateTime()
validator on the group I do some logic to validate the formGroup and if it's invalid I do the following:
control.get('startTime').setErrors(MY_CUSTOM_ERROR) // MY_CUSTOM_ERROR is a valid error object
or the same except on control.get('stopTime')
. This works the FIRST time and appropriately sets the error on the FormControls when they first enter the invalid state. The second time though, they have empty error objects.
I set debug points to narrow down what's happening and my FormGroup validator is appropriately setting the error on the control again, but it looks like something within Angular's code is clearing the error object.
How can I set error objects on a control from a FormGroup validator?
EDIT:
I'm not sure what was removing my error, but I was able to change my error object structure to an Array of errors, and then set them on the FormGroup instead.
Instead of the formControls startTime or stopTime having errors, I now set them on the FormGroup and my UI will check for any relevant feedback inside the FormGroup's errors.
Have you tried to update value and validity before setting the error?
I had the same issue and this helped:
this.form.get('startDate')?.markAsTouched();
this.form.get('startDate')?.updateValueAndValidity();
this.form.get('startDate')?.setErrors({ invalidDateTime: true });
I found this solution from a different question on github: github solution to how to setErrors in FormGroups
but fromgroup.valid didn't take this error into account in my code so I manually checked for it with a boolean parameter, in this example:
pseudo-code:
const timeError: boolean = "startTime before new Date()"
const formStartTimeControl = this.time.controls.startTime;
if (timeError) {
setTimeout(() => {
formStartTimeControl.markAsDirty();
formStartTimeControl.markAsTouched();
formStartTimeControl.setErrors(MY_CUSTOM_ERROR);
}, 1);
} else {
setTimeout(() => {
formStartTimeControl.markAsDirty();
formStartTimeControl.markAsTouched();
formStartTimeControl.setErrors(null);
}, 1);
}
// [...] other code
if(formGroup.valid && !timeError){
// continue with submitting code
}
but that and that you have to set a timeout for the code to work makes it look like a dodgy solution to me, would be interesting to see if there is a better one out there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With