Back to course

Implementing Custom Validators

The Complete Angular Developer: From Zero to Hero

48. Implementing Custom Validators

Built-in validators are often insufficient. Custom validators allow us to implement application-specific rules (e.g., checking password complexity, verifying unique usernames locally).

Validator Structure

A custom validator is a simple function that takes a FormControl (or AbstractControl) instance and returns either:

  • null if validation is successful.
  • A validation error object (e.g., { 'forbiddenName': { value: control.value } }) if validation fails.

Example: Forbidden Name Validator

We want to prevent users from selecting 'Test' or 'Admin' as a username.

typescript import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';

export class CustomValidators {

// A factory function that returns the validator function static forbiddenName(forbiddenWords: string[]): ValidatorFn { // This is the validator function that Angular calls return (control: AbstractControl): ValidationErrors | null => {

  const currentName = control.value as string;
  if (!currentName) { return null; }
  
  const isForbidden = forbiddenWords.includes(currentName.toLowerCase());
  
  // If forbidden, return the error object
  return isForbidden ? { 'forbiddenName': { value: control.value } } : null;
};

} }

Applying the Custom Validator

typescript // In the component where the form is defined this.userForm = this.fb.group({ username: ['', [ Validators.required, // Use the factory function to apply the validator CustomValidators.forbiddenName(['admin', 'root']) ]] });

Now we can check for the error key 'forbiddenName' in the template.