Angular 4 remove required validator conditionally

84,264

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

Share:
84,264
Ali Shahzad
Author by

Ali Shahzad

Updated on December 21, 2021

Comments

  • Ali Shahzad
    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
    Zaker about 6 years
    This 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
    rmcsharry about 6 years
    @Zaker Please post a new question, with your code, and link to this question.
  • Caleb Swank
    Caleb Swank over 5 years
    for 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
    Raj over 5 years
    @CalebSwank Thanks for adding this. setErrors(null) and setValidators(null); works charmingly. :-)
  • LameCoder
    LameCoder over 5 years
    I 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
    dudewad over 5 years
    Right, 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
    Ben Racicot over 5 years
    I'm here because my control with min/maxlength set still gets required error on an empty field.
  • brijmcq
    brijmcq over 4 years
    this is the best solution for me
  • ohdev
    ohdev over 4 years
    But after removing errros when you add required validator again, you need add errors :(.
  • borchvm
    borchvm over 3 years
    While 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
    Peter van Kekem over 3 years
    clearValidators() doesn't accept arguments, and clears all validators. See angular.io/api/forms/AbstractControl#clearValidators
  • MD. RAKIB HASAN
    MD. RAKIB HASAN over 2 years
    There are no parameters on clearValidators() . Why people up vote this wrong info..!!!
  • Zinedine Benkhider
    Zinedine Benkhider over 2 years
    It work for me. It make the form valid when the value of the item is null.