Search code examples
angulartypescriptangular-materialangular8angular-reactive-forms

Angular Validators on Object Members in Reactive Form


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?


Solution

  • 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)])],