In Angular, how to add Validator to FormControl after control is created?
AngularFormsAngular Reactive-FormsAngular 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