Angular Form Validation and Custom Validators

Angular Form Validation and Custom Validators

Angular provides built-in validators and a clean API for writing custom synchronous and asynchronous validators.

Built-in Validators

import { Validators } from '@angular/forms';

this.fb.group({
  username: ['', [
    Validators.required,
    Validators.minLength(3),
    Validators.maxLength(20),
    Validators.pattern(/^[a-zA-Z0-9_]+$/),
  ]],
  age:  [null, [Validators.required, Validators.min(18), Validators.max(120)]],
  site: ['',   Validators.compose([Validators.required, Validators.url])],
});

Custom Synchronous Validator

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

export function noSpacesValidator(): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    return /\s/.test(control.value)
      ? { noSpaces: { value: control.value } }
      : null;
  };
}

// Usage
username: ['', [Validators.required, noSpacesValidator()]]

Cross-Field Validator (Password Match)

export function passwordMatchValidator(control: AbstractControl): ValidationErrors | null {
  const password = control.get('password');
  const confirm  = control.get('confirmPassword');
  if (password && confirm && password.value !== confirm.value) {
    return { passwordMismatch: true };
  }
  return null;
}

// Apply at group level
this.fb.group({ password: [''], confirmPassword: [''] }, { validators: passwordMatchValidator })

Async Validator (Check Username Availability)

export function usernameAvailable(service: UserService): AsyncValidatorFn {
  return (control: AbstractControl): Observable<ValidationErrors | null> => {
    return service.checkUsername(control.value).pipe(
      debounceTime(400),
      map(taken => taken ? { usernameTaken: true } : null),
      catchError(() => of(null))
    );
  };
}
AngularJS {"id":68,"topic_id":33,"name":"Angular Forms","slug":"angular-forms","image":null,"description":"<p>Build powerful forms with validation using both Template-Driven and Reactive Forms approaches.<\/p>","icon":null,"class":null,"color":null,"status":0,"order":6,"created_at":"2026-05-04T21:01:53.000000Z","updated_at":"2026-05-04T21:01:53.000000Z"} - List of Contents

Related Tutorials: