0
votes

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.

1
Not really enough information to reproduce the issue. Code here looks fine to me. Perhaps create a plunker that showcases the issue? - AJT82
Is it definitely executing the appropriate branch of this logic? - DeborahK
Have you tried this: this.category_type.clearValidators(); - DeborahK
I believe it's because you set the validators first, and then the getCategoryTypes() is not ran again maybe? Not enough code, But I faced something similar with checkboxes. Essentially, you have to remove the validators when a value changes or fails to meet the requirement as DeborahK mentioned with this.control.clearValidators(); - Taranjit Kang
@DeborahK Yes it is definitely executing the else branch, I tested that with logging to console. I also tried clearValidators(). - rmcsharry

1 Answers

1
votes

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();
    };
  }