Nico Schuck
Nico Schuck

Reputation: 972

Angular custom Form Validator use other Controlers

I try to implement a custom Validator for my Angular 9 Form. The validation is a little bit difficult.

Because a couple of fields depends on the selection of a select input.

For example if I select option one of my select, Formfield 3 is required.

But if I select option two, Formfield 5 is required.

That's why I have writte a custom Validator:

export class FormComponent {
  public form: FormGroup = new FormGroup({
    ...
    selectField: new FormControl(null, [Validators.required]),
    ...
    formField3: new FormControl(null, [this.validatorArtAende]),
    formField4: new FormControl(),
    formField5: new FormControl(null, [this.validatorArtAender])
  });

  validator (control: AbstractControl) => {
    if (this.form.value.selectField === 'option1' && control.value.length === 0) {
      return { required: true };
    }
    return null;
  }
}

The issue is that this.form is unknwon (Cannot read property 'form' of undefined). So is there any option to pass the form or the value of a diffrent Control to the custom validator?

Upvotes: 1

Views: 1241

Answers (2)

Andrew HB
Andrew HB

Reputation: 412

Just to update this question as I assume things have moved on in the Angular world as I needed to achieve this very same thing today. You can access all other controls within the form directly from control passed into the validator function using: -

const compareControl = control.get(controlName);

I found using the control.parent approach caused numerous issues with typing and also added additional complexity which is not required.

Upvotes: 1

spots
spots

Reputation: 2708

According to the documentation, AbstractControl has a Parent property. You should be able to use that to traverse to your parent FormGroup and then to the selectField inside your validator.

validator (control: AbstractControl) => {
  if (control.parent && control.parent.controls['selectField'] === 'option1' && control.value.length === 0) {
    return { required: true };
  }
  return null;
}

Upvotes: 3

Related Questions