rmcsharry
rmcsharry

Reputation: 5552

Angular2/4 - reactive forms, how to dynamically set and clear required validator

I have a reactive from, with two select dropdowns. Depending on the value selected in the first, the second may or may not be required.

This is the code that fires when the value changes on the first one. It basically searches an array to see if their are matching types and if there are it assigns them to the second dropdown, adds the required validator. If not, the control is disabled and the validator is removed.

However, the field remains required in the else part and the whole form is marked invalid. So what is missing?

  getCategoryTypes(value: string) {
    let types = this.categories.find(v => v.name === value);
    if (types) {
      this.categoryTypes = types.category_types;
      this.category_type.setValue("");
      this.category_type.setValidators([Validators.required]);
      this.category_type.updateValueAndValidity();
    }
    else {
      this.categoryTypes = [];
      this.category_type.setValidators(null);
      this.category_type.updateValueAndValidity();
    };
  }

Fyi:

category_type: FormControl;

UPDATE

In the Docs I discovered this:

"These statuses are mutually exclusive, so a control cannot be both valid AND invalid or invalid AND disabled."

and

"Disabled controls are exempt from validation checks and are not included in the aggregate value of their ancestor controls."

So disabling the control should automatically remove the validation and thus mark the control as being valid.

Upvotes: 0

Views: 2053

Answers (1)

rmcsharry
rmcsharry

Reputation: 5552

The if (types) check was not working but I also discovered it is not necessary to remove and re-add the validations, I can just disable and re-enable the control. So the solution is:

  getCategoryTypes(value: string) {
    let types = this.categories.find(v => v.name === value).category_types;
    if (types.length > 0) {
      this.categoryTypes = types;
      this.category_type.setValue("");
      this.category_type.enable();
      this.category_type.updateValueAndValidity();
    }
    else {
      this.categoryTypes = [];
      this.category_type.disable();
      this.category_type.updateValueAndValidity();
    };
  }

Upvotes: 0

Related Questions