How to do required-if in Angular Reactive Forms?

Viewed 7952

I have a reactive form and based on the property fooRequired I want to set the field to be required or not.

I can't change that because it set at initial. so what can I do?

fooRequired = false;

form = new FormGroup({
 foo: new FormControl(null, [Validators.required])
});

toggle() { this.fooRequired = !this.fooRequired; }
3 Answers

The following will do the trick:

toggle() {
  this.fooRequired = !this.fooRequired;
  this.form.controls.foo.setValidators(this.fooRequired ? null : [Validators.required]);
  this.form.controls.foo.updateValueAndValidity();
}

Here, based on the fooRequired boolean, the validators are set or removed. Finally, the new form control settings are updated.

You can use a custom function that gonna be responsible for adding or removing the Validators

export function conditionalValidator(
  predicate: BooleanFn,
  validator: ValidatorFn,
  errorNamespace?: string
): ValidatorFn {
  return formControl => {
    if (!formControl.parent) {
      return null;
    }
    let error = null;
    if (predicate()) {
      error = validator(formControl);
    }
    if (errorNamespace && error) {
      const customError = {};
      customError[errorNamespace] = error;
      error = customError;
    }
    return error;
  };
}

Then you can use it inside you form control:

this.myForm = this.fb.group({
  myEmailField: [
    "",
    [
      // some normal validatiors
      Validators.maxLength(250),
      Validators.minLength(5),
      Validators.pattern(/.+@.+\..+/),
      // custom validation
      conditionalValidator(
        // depends on fooRequired value
        () => this.fooRequired,
        Validators.required,
        "illuminatiError"
      )
    ]
  ]
});

Finally you can toggle the value of fooRequired and see the result:

  toggle() {
    this.fooRequired = !this.fooRequired;
    this.myForm.get("myEmailField").updateValueAndValidity();
  }

Here is a live demo to help you with implementing the above answer

Related