1

I try to implement a validator in Angular 11 but i get the compliation error: Type '(controlArray: FormArray) => ValidationErrors | null' is not assignable to type 'ValidatorFn'. Any ideas how to fix this error?

Validator-class:

import { FormArray, ValidationErrors } from "@angular/forms";

export class BookValidators {
    static atLeastOneAuthor(controlArray: FormArray): ValidationErrors | null {
        if(controlArray.controls.some(el => el.value)){
            return null;
        }else{
            return{
                atLeastOneAuthor: {
                    valid: false
                }
            }
        }
    }
}

The calling class

constructor(private fb: FormBuilder){}

private buildAuthorsArray(values: string[]): FormArray{
    // BookValidators.atLeastOneAuthor is now underlined with the error.
    return this.fb.array(values, BookValidators.atLeastOneAuthor);
}

2 Answers 2

7

Good answer, but i had to modify it a bit to make it work. Here is my solution:

  static atLeastOneAuthor(): ValidatorFn {
    return (control: AbstractControl) => {
      const controlArray = control as FormArray;
      if (controlArray.controls.some(el => el.value)) {
        return null;
      } else {
        return {
          atLeastOneAuthor: { valid: false }
        }
      }
    }
  }
Sign up to request clarification or add additional context in comments.

1 Comment

Indeed, that's the "proper" solution. I don't get why we have to first type the parameter as "control" to then cast it as "group" or "array" for your example ... I'd have to dive a little deeper in the API I guess :)
1

The parameter calls for a factory function that returns a ValidatorFn, not the function itself. See the format here: https://angular.io/guide/form-validation#defining-custom-validators. Here is an edit to your code:

static atLeastOneAuthor(): ValidatorFn {
  return (controlArray: FormArray) => {
    if (controlArray.controls.some(el => el.value)) {
        return null;
    } else {
        return {
            atLeastOneAuthor: {
                valid: false
            }
        }
    }
  };
}

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.