angularangular2-formsangular2-formbuilder

Why should I use Validators.compose()?


I have a field I want to validate with multiple validators.
Using the Module Driven approach the code looks likes this:

this.exampleForm = this.fb.group({
  date_start : [
    '',
    Validators.compose([
      Validators.required,
      Validators.pattern("[0-9]{2}-[0-9]{2}-[0-9]{4}")
    ])]
})

But I can also write this withouth Validators.compose() like:

this.exampleForm = this.fb.group({
  date_start : [
    '',
    [
      Validators.required,
      Validators.pattern("[0-9]{2}-[0-9]{2}-[0-9]{4}")
    ]
  ]
})

And it works just fine. Personally I prefer the 2nd version (without compose), less code and better readability. And this begs the question, why should I use Validators.compose()?


Solution

  • When we create new FormControl/FormGroup/FormArray(AbstractControl) - coerceToValidator is called.

    function coerceToValidator(
        validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null): ValidatorFn|
        null {
      const validator =
          (isOptionsObj(validatorOrOpts) ? (validatorOrOpts as AbstractControlOptions).validators :
                                           validatorOrOpts) as ValidatorFn |
          ValidatorFn[] | null;
    
      return Array.isArray(validator) ? composeValidators(validator) : validator || null;
    }
    
    export function composeValidators(validators: Array<Validator|Function>): ValidatorFn|null {
      return validators != null ? Validators.compose(validators.map(normalizeValidator)) : null;
    }
    

    So there is no need to compose validators before we pass it to an AbstractControl.

    6/13/16 was added feat(forms): compose validator fns automatically if arrays from now on, Validators.compose is there for backward compatibility.