0

We have an Angular Reactive Formbuilder

this.formBuilderGroup({
  'productType':['',[Validators.required, Validators.min(3)]],
  'deliveryCategory':['',[Validators.required, Validators.max(8)]]
})

They are actually driven from Material select dropdowns, and give Dto Objects. How do I have validators on actual Object members within?

such as productType.productTypeId Validator min is 1.

and deliveryCategory.deliveryCategoryNo min 1?

Validators.min is currently only on whole object.

How can I write custom Validator that will take object as object member as parameters? Or is there more optimal way?

3
  • Whatever the [value] of the select is is what will get the validation rule. It's not the whole object. Can you create a StackBlitz? Commented Mar 18, 2020 at 19:36
  • currently our value is the whole DTO object Commented Mar 18, 2020 at 19:38
  • Ah. You will need a custom validator then. Commented Mar 18, 2020 at 19:39

3 Answers 3

2

This needs a custom validator, which can be written like this:

// pass in property to validate and list of validators to run on it
export function validateProperty(property: string, validators: ValidatorFn[]): ValidatorFn {
  return (control: AbstractControl): { [key: string]: any } | null => {
    // get the value and assign it to a new form control
    const propertyVal = control.value && control.value[property];
    const newFc = new FormControl(propertyVal);
    // run the validators on the new control and keep the ones that fail
    const failedValidators = validators.map(v => v(newFc)).filter(v => !!v);
    // if any fail, return the list of failures, else valid
    return failedValidators.length ? {invalidProperty: failedValidators} : null;
  };
}

usage:

'productType':['', validateProperty('propertyToValidate', [Validators.required, Validators.min(3)])],
Sign up to request clarification or add additional context in comments.

Comments

1

the function signature of the accepted solution should be..

validateProperty(property: string, validators: ValidatorFn[]): ValidatorFn

Comments

0

If you want to return the validation errors structure just like Angular does it.

export function validateProperty(property: string, validators: ValidatorFn[]): ValidatorFn {
  return (control: AbstractControl): { [key: string]: any } | null => {
    const propertyVal = control.value && control.value[property];
    const propertyControl = new FormControl(propertyVal);
    const errors = validators.map(v => v(propertyControl))
      .filter(v => !!v)
      .reduce((a, v) => ({ ...a, ...v}), {});

    return Object.keys(errors).length ? errors : null;
  };
};

Comments

Your Answer

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