angularangular-reactive-formsangular4-formscustom-validators

Right way of creating a class to hold all the custom validations in angular 4


I have created a class which holds all the custom validations for my application. Just wanted to know if this is the right way to do so. I saw some example online and came up with this code. Does each method have to be static? If i remove the static key work, i get compilation errors.

import { FormControl, ValidatorFn } from '@angular/forms';

export class FormValidator {

     static validategreater(maxVal, minVal): ValidatorFn {
    return (control: FormControl) => {
      if (control.dirty) {

          if (enteredValue > maxVal) {
            returnObj['greaterError'] = true;
          }
       if (Object.keys(returnObj).length > 0) {
          return returnObj;
        }
      }
      return null;
    };
  }

}

Solution

  • There is no standard for how to store custom validators, it only has to be a function that implements the ValidatorFn contract. But it is recommended that you follow the angular-forms' standard as developers would already be used to it so it make your code easier to understand.

    You can store on a class using static members (as you suggested):

    class MyCustomValidators {
        // it has to be called like MyCustomValidators.withParams(123, 456)
        static withParams(param1, param2) : ValidatorFn {
           return (control: FormControl) => { /*implementation*/ }
        }
    
        // it has to be called like MyCustomValidators.withoutParams1
        static withoutParams1(control: FormControl) {
           /*implementation*/
        }
    
        // it has to be called like MyCustomValidators.withoutParams2()
        static withoutParams2() : ValidatorFn {
           return (control: FormControl) => { /*implementation*/ }
        }
    }
    

    Or functions only:

    export const MyCustomValidator = (control: FormControl) => { /*implementation*/ }
    
    export const MyCustomValidator2 = (param1) => (control: FormControl) => {
        /*implementation*/
    }
    

    As you can see, the important part is the (control: FormControl) => { /*implementation*/ } function; therefore, you can store your ValidatorFn in a variety of ways as long as typescript allows.

    In addition, there are cases when it is good to organize validators based on their context, for example, CommonValidators, CustomerValidators, ProductValidators, etc. This helps you to keep the responsibility of the aggregated validator class more clear, also don't mix more specific validators with general validators making code maintenance easier for example.

    In conclusion, you can chose whatever standard you want to store your custom validations; although, using classes with static methods is better because it keeps the same standard angular-forms uses, so it is much more intuitive to use your validators as it is a well known standard.

    If i remove the static key work, i get compilation errors.

    If you remove the static, you would have to create an instance of the class to have access to the validator member.

    new FormValidator().validategreater(1,2)