In Angular, how to add Validator to FormControl after control is created?

AngularFormsAngular Reactive-Forms

Angular Problem Overview


We have a component that has a dynamically built form. The code to add a control with validators might look like this:

var c = new FormControl('', Validators.required);

But let's say that I want to add 2nd Validator later. How can we accomplish this? We cannot find any documentation on this online. I did find though in the form controls there is setValidators

this.form.controls["firstName"].setValidators 

but it is not clear how to add a new or custom validator.

Angular Solutions


Solution 1 - Angular

You simply pass the FormControl an array of validators.

Here's an example showing how you can add validators to an existing FormControl:

this.form.controls["firstName"].setValidators([Validators.minLength(1), Validators.maxLength(30)]);

Note, this will reset any existing validators you added when you created the FormControl.

Angular 12 update

Since Angular 12, if you want to add new validators to the form without removing the existing validators, you can use addValidator:

this.form.controls["firstName"].addValidators([Validators.minLength(1), Validators.maxLength(30)]);

Solution 2 - Angular

To add onto what @Delosdos has posted.

Set a validator for a control in the FormGroup: this.myForm.controls['controlName'].setValidators([Validators.required])

Remove the validator from the control in the FormGroup: this.myForm.controls['controlName'].clearValidators()

Update the FormGroup once you have run either of the above lines. this.myForm.controls['controlName'].updateValueAndValidity()

This is an amazing way to programmatically set your form validation.

Solution 3 - Angular

If you are using reactiveFormModule and have formGroup defined like this:

public exampleForm = new FormGroup({
        name: new FormControl('Test name', [Validators.required, Validators.minLength(3)]),
        email: new FormControl('[email protected]', [Validators.required, Validators.maxLength(50)]),
        age: new FormControl(45, [Validators.min(18), Validators.max(65)])
});

than you are able to add a new validator (and keep old ones) to FormControl with this approach:

this.exampleForm.get('age').setValidators([
        Validators.pattern('^[0-9]*$'),
        this.exampleForm.get('age').validator
]);
this.exampleForm.get('email').setValidators([
        Validators.email,
        this.exampleForm.get('email').validator
]);

FormControl.validator returns a compose validator containing all previously defined validators.

Solution 4 - Angular

I think the selected answer is not correct, as the original question is "how to add a new validator after create the formControl".

As far as I know, that's not possible. The only thing you can do, is create the array of validators dynamicaly.

But what we miss is to have a function addValidator() to not override the validators already added to the formControl. If anybody has an answer for that requirement, would be nice to be posted here.

Solution 5 - Angular

If you need to remove some existing validation on the added form control then call below function on the control

this.form.controls["name"].clearValidators();

After that you need to call below function for update the form controls it will be effect immediately on the form controls.

this.form.controls['name'].updateValueAndValidity();

If you need to add some validation on the already added form control then call below function on the control

this.signupForm.controls['name'].setValidators([Validators.required]);

After that call updateValueAndValidity() function immediately, so it will be reflect instantly.

Solution 6 - Angular

In addition to Eduard Void answer here's the addValidators method:

declare module '@angular/forms' {
  interface FormControl {
    addValidators(validators: ValidatorFn[]): void;
  }
}

FormControl.prototype.addValidators = function(this: FormControl, validators: ValidatorFn[]) {
  if (!validators || !validators.length) {
    return;
  }

  this.clearValidators();
  this.setValidators( this.validator ? [ this.validator, ...validators ] : validators );
};

Using it you can set validators dynamically:

some_form_control.addValidators([ first_validator, second_validator ]);
some_form_control.addValidators([ third_validator ]);

Solution 7 - Angular

A simple solution would be to first get all the validators in the form control and assign a new validatorFn to it when needed code will go like this.

//get existing validators and assign a new validator

const formControl = this.form.controls["firstName"];

 const validators: ValidatorFn[] = !!formControl.validator ?
  [formControl.validator, Validators.required] :
  [Validators.required];

formControl.setValidators(validators);

formControl.validtor holds the existing validators (not asyncValidators) we check if it's not null using ternary and add to it ( here we add the required validator to it), otherwise, we just assign our new validator

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmelegantView Question on Stackoverflow
Solution 1 - AngularAndy-DelosdosView Answer on Stackoverflow
Solution 2 - AngularshammelburgView Answer on Stackoverflow
Solution 3 - AngularEduard VoidView Answer on Stackoverflow
Solution 4 - Angularuser2992476View Answer on Stackoverflow
Solution 5 - AngularRamesh singh shekhawatView Answer on Stackoverflow
Solution 6 - Angularlucifer63View Answer on Stackoverflow
Solution 7 - AngulardarkelView Answer on Stackoverflow