Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular validation on reactive form should toggle on or off if empty, but does not toggle if input is emptied

I've built a simple form using Angular Reactive Forms. I have a custom Validator function, which checks the format of a phone number input. I want to allow an empty input if the users chooses not to enter a phone number, but then validate their entry if they enter one.

To achieve this, I subscribe to the value changes on the form control and use the setValidators method to toggle the validation if the field is empty or not:

phoneControl.valueChanges.subscribe(() => {
  if (phoneControl.value === "") {
    phoneControl.setValidators(null);
  } else {
    phoneControl.setValidators(this.phoneValidator());
  }
});

Please see the full code on StackBlitz.

The code works initially, form.valid is true. When I enter a number it turns on the validation and then successfully validates it according to my RegEx and shows an error.

However, when I empty the field, the error does not disappear and the form form is still invalid, even though my code should set the validator to null. You can see this in the StackBlitz example above.

I can't figure out why this is happening. Any ideas?

like image 871
shrewdbeans Avatar asked Dec 31 '22 18:12

shrewdbeans


2 Answers

When dynamically setting validators, we need to call updateValueAndValidity(). Also remember to add emitEvent: false, that means that the valueChanges will not be triggered (to prevent looping). So change your code to:

phoneControl.valueChanges.subscribe(() => {
  if (phoneControl.value === "") {
    phoneControl.setValidators(null);
    // or
    // phoneControl.setValidators([]);
    // or as mentioned by Tilak
    // phoneControl.clearValidators();
  } else {
    phoneControl.setValidators(this.phoneValidator());
  }
  phoneControl.updateValueAndValidity({emitEvent: false});
});

Your StackBlitz

like image 63
AT82 Avatar answered Jan 13 '23 09:01

AT82


I will recommend you to do this way -

if (phoneControl.value === "") {
        phoneControl.clearValidators();
} else {
        phoneControl.setValidators(this.phoneValidator());
}
phoneControl.updateValueAndValidity({emitEvent: false});

Clearing validator is a better way than setting it to null.

like image 41
Tilak Dewangan Avatar answered Jan 13 '23 09:01

Tilak Dewangan