All topics
Formsintermediate

Custom Validators

Explain how to write a synchronous custom validator function matching Angular's ValidatorFn signature.

Angular's built-in validators (Validators.required, Validators.email, Validators.minLength, and so on) cover common cases, but real forms frequently need domain-specific rules — a password matching a policy, a username that can't contain spaces, a date that must be in the future — and a custom validator is simply a function matching the ValidatorFn signature: it receives an AbstractControl and returns either null (valid) or a ValidationErrors object (invalid), where the object's keys become identifiers you can check in the template to show specific error messages.

A custom validator is like a specialized inspector added to an assembly line's existing quality-control checklist — it plugs into the same pass/fail reporting system as every other inspector, just checking for a rule specific to your product.

Key Concepts

1
A well-designed custom validator is a pure function with no side effects, ideally taking any configuration it needs (like a regex pattern or a threshold value) as parameters to a factory function that returns the actual ValidatorFn — this is exactly the shape of Angular's own Validators.minLength(3), which is itself a factory returning a validator function closed over the 3.
ValidatorFnValidators.minLength(3)3
2
A validator can be applied to a single FormControl (checking that control's own value in isolation) or to a FormGroup/FormArray (checking relationships between multiple sibling controls, which is exactly the cross-field validation case — like confirming two password fields match) — the same ValidatorFn signature works at both levels since a FormGroup is itself an AbstractControl.
FormControlFormGroupFormArrayValidatorFnAbstractControl
3
Interviewers often ask you to write one live, since it's compact enough to complete in a few minutes but demonstrates the ValidatorFn signature, the ValidationErrors | null return convention, and how validation errors surface through control.errors and control.hasError('key') in the template — foundational knowledge for any non-trivial reactive form.
ValidatorFnValidationErrors | nullcontrol.errorscontrol.hasError('key')