Angular 4 remove required validator conditionally
Solution 1
if you want to add validation try this one.
saveDraft() {
this.form.get('title').setValidators([Validators.required, Validators.minLength(3)]);
this.form.get('title').updateValueAndValidity();
}
if you want to remove validators try this one.
saveDraft() {
this.form.get('title').clearValidators();
this.form.get('title').updateValueAndValidity();
}
Solution 2
I don't like clearing and setting validators, as I have to repeat all static validators (patterns, min, max, etc.) just to have a dynamic "required" validator.
I use a conditional validator:
export function conditionalValidator(condFn: (control: AbstractControl) => boolean,
validators: ValidatorFn | ValidatorFn[]): ValidatorFn {
return (control) => {
if (!condFn(control)) {
return null;
}
if (!Array.isArray(validators)) {
return validators(control);
}
return validators.map(v => v(control)).reduce((errors, result) =>
result === null ? errors :
(Object.assign(errors || {}, result))
);
};
}
I can then mix a static validator with a dynamic "required" condition:
this.fb.group({name: ['', [Validators.minLength(4),
conditionalValidator(this.isClientProj, Validators.required)]]}
Where isClientProj()
is the condition function (closure)
Solution 3
we can use setValidators
to remove validation.
setValidators(newValidator: ValidatorFn | ValidatorFn[]): void
setValidators() - setValidators programmatically adds the sync validators. This method will remove all the previously added sync or async validators.
this.form.get('title').setValidators(null);
this.form.get('title').setErrors(null);
Solution 4
You can use: AbstractControl.removeValidators(validator: ValidatorFn)
Not sure if it is possible in angular 4, but definately in Angular 12 and higher.
It needs however, a reference to the exact same function. Just giving it Validators.required does not work. You need to create a unique reference to it:
requiredValidator = Validators.required;
this.form = this._fb.group({
title: ['', [this.requiredValidator, Validators.minLength(3), Validators.maxLength(50)]],
description: ['', [this.requiredValidator, Validators.minLength(3)]]
});
saveDraft() {
this.title.removeValidator(this.requiredValidator);
}
get title(): AbstractControl {
return this.form.get('title');
}
Solution 5
To Add Validators:
this.form = this._fb.group({
title: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(50)]],
description: ['', [Validators.required, Validators.minLength(3)]]
});
or
this.form.get('title').setValidators([Validators.required,Validators.minLength(3),
Validators.maxLength(50)]);
To Remove the 'Required' validator only, you can reset the validators.
saveDraft() {
this.form.get('title').setValidators([Validators.minLength(3), Validators.maxLength(50)]);
this.form.get('title').updateValueAndValidity();
}
updateValueAndValidity determines how the control propagates changes and emits events when the value and validators are changed
Ali Shahzad
Updated on December 21, 2021Comments
-
Ali Shahzad over 2 years
In Angular 4 app I have a form model like this:
this.form = this._fb.group({ title: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(50)]], description: ['', [Validators.required, Validators.minLength(3)]] });
Now what I want is to remove dynamically only the required validator from the control validators array. Something like this:
saveDraft() { this.form.controls['title'].removeValidator('required'); //Just a fake implementation for demonstration }
This question is not the duplicate of the mentioned question. My case is different I just want to remove the required validator unknowingly the other ones.
-
Zaker about 6 yearsThis doesn't work for me. In my case I have dropdown on change event I am calling a function a condition to set the validators as above. Any suggestions what might be wrong.
-
rmcsharry about 6 years@Zaker Please post a new question, with your code, and link to this question.
-
Caleb Swank over 5 yearsfor anyone else running into this issue, I had to do a this.form.get('title').setValidators(null); this.form.get('title').setErrors(null) in order to ensure this.form.valid = true
-
Raj over 5 years@CalebSwank Thanks for adding this.
setErrors(null)
andsetValidators(null);
works charmingly. :-) -
LameCoder over 5 yearsI think something to note here is that something needs to be done to insure that a change in the condition value triggers revalidation. I don't think a change in a checkbox will trigger validation on other form fields.
-
dudewad over 5 yearsRight, and this is the problem I am currently trying to solve. If you're in an invalid state and the validator condition changes to false, then the form is still invalid unless you manually kick off a validation cycle which is less than desirable. The Validator interface does define a changed event hook which as far as I can tell is what Angular hooks into to trigger validation again, so I'm going to try that.
-
Ben Racicot over 5 yearsI'm here because my control with min/maxlength set still gets
required
error on an empty field. -
brijmcq over 4 yearsthis is the best solution for me
-
ohdev over 4 yearsBut after removing errros when you add required validator again, you need add errors :(.
-
borchvm over 3 yearsWhile this code may provide a solution to the question, it's better to add context as to why/how it works. This can help future users learn, and apply that knowledge to their own code. You are also likely to have positive feedback from users in the form of upvotes, when the code is explained.
-
Peter van Kekem over 3 yearsclearValidators() doesn't accept arguments, and clears all validators. See angular.io/api/forms/AbstractControl#clearValidators
-
MD. RAKIB HASAN over 2 yearsThere are no parameters on
clearValidators()
. Why people up vote this wrong info..!!! -
Zinedine Benkhider over 2 yearsIt work for me. It make the form valid when the value of the item is null.