2

I am looking to remove the specific validator from validator array in order to set the controls again when some values changed.

I know normal solution where I need to set validators again and again.

checked(event: MatCheckboxClickAction): void {
    const control = (this.form.get(
        'information',
    ) as FormGroup).controls.data1;
    if (event) {
        this.updateRequiredValidator(control);
    } else {
        control.setValidators([
            Validators.maxLength(9), Validators.minLength(2)
        ]);
        control.updateValueAndValidity();
    }
}

updateRequiredValidator(control: AbstractControl): void {
    control.setValidators([
        Validators.required,
        ...(control?.validator ? [control?.validator as ValidatorFn] : []),
    ]);
    control.updateValueAndValidity();
}

I would like to just removed the Validators.required on else part instead of setting validators again and again.

2 Answers 2

4

I think that the best bet is use a "customValidator" like "requireIf".

  requiredIf(field: string) {
    return (control: FormControl):{required:boolean}|null => {
      const form = control.parent as FormGroup;
      const check=form?form.get(field):null
      if (form && check && check.value)
        return !control.value ? { required: true } : null;

      return null;
    };
  }
//e.g.
this.form=new FormGroup({
   check:new FormControl();
   data1:new FormControl(null,this.requiredIf('check'))
})

But be carefull, when check change you need use

this.form.get('data1').updateValueAndValidity()

in the stackblitz I use mat-angular and use the (change) to make the updateValueAndValidity

UPDATE to defined the typedef of the function

requiredIf(field: string):ValidatorFn {
    return (control: AbstractControl):{required:boolean}|null => {
      ....
    }
}
Sign up to request clarification or add additional context in comments.

7 Comments

just a small question.. How it can work for nested groups?
form = new FormGroup({ check: new FormControl(true), val: new FormGroup({ check: new FormControl(true), }), data1: new FormControl(null, [ this.requiredIf("val.check"), Validators.maxLength(10) ]) });
Type '(control: FormControl) => { required: boolean;} | null' is not assignable to type 'ValidatorFn'. Types of parameters 'control' and 'control' are incompatible. I do get following error in the stackblitz.
app, If is in a nested group you need "get" the form, you should use parent.parent, e.g. if your formgroup is {form:{check,{some:data1}}, and you can use in get the dot notation, e.g. form('subgroup.check'). If you get an error in your validator, use AbstractControl instead FormControl
the logic is the same, you need "get" the two checkbox (first find the formgroup, then the two checkbox using get())
|
1

Instead of adding and removing the validators, you can create the custom validator function that can check all possible error and set error using setError method of AbscractControl

2 Comments

but I need to remove the validators.required based on the check condition
you can put custom validator on FormGroup it self

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.