Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular FormGroup validator doesn't preserve setError on FormControl

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.

like image 585
JamesRichardson Avatar asked Sep 16 '25 14:09

JamesRichardson


2 Answers

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 });
like image 80
Ahmed Mostafa Avatar answered Sep 18 '25 05:09

Ahmed Mostafa


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.

like image 40
DrakoGZ Avatar answered Sep 18 '25 03:09

DrakoGZ