Search code examples
angularangular-validation

Angular: Do validators remove and re-assign errors on value changes (when they run)?


I have created the below custom group validator which checks if passwords match. It works great however there is something I do not know WHY IT WORKS.

export class CustomGroupValidators {
   static matchFields(field1: string, field2: string, errorKey: string): ValidatorFn {
      return (group: AbstractControl): ValidationErrors | null => {
         const firstField = group.get(field1);
         const secondField = group.get(field2);

         if (firstField?.value !== secondField?.value) {
            secondField?.setErrors({ mismatch: true });
            return { [errorKey]: true };
         } else {
            return null;
         }
      };
   };
}
  • The validator also sets an error to the second field if the matchFields validator itself returns error so I can provide feedback to the user.

As you can see I do not clear or reset any errors, however when first & second fields match validation works right and second field is valid - as per my wish. Does this mean that whenever a validator runs (either on a field or a group), it clears all the errors and re-evaluates / re-attaches those needed? Otherwise why don't I encounter a bug where "mismatch" error is still true when prior value caused the error to be set but current value is good?

Also I do not clearly understand under which events validators run in general. I know they run on value changes however are there any other circumstances under which they run in addition to that?


Solution

  • All the validators assigned to an AbstractControl are re-run each time value of the control changes AND the control is enabled.

    Note that the changes traverse up the tree, so changing a FormControl inside a FormGroup will change the value of both the control and the group - with FormControl taking precedence.

    This is a part of code responsible for running validators when value changes.

    So in your case, angular will first run validators on your secondField. In case of no validators (or validators returning null), errors array is empty and status is set to VALID.

    Then, the same happens for your FormGroup - errors on the group are cleared, and your validators are run.