Course Progress 70%

Angular Custom Validators

Angular Custom Validators का use तब किया जाता है जब built-in validators आपकी business requirements को पूरा नहीं करते। Real-world applications में अक्सर ऐसी validation logic चाहिए होती है जो simple required, email या minLength से कहीं ज्यादा complex होती है। Angular आपको synchronous और asynchronous दोनों तरह के custom validators बनाने की पूरी flexibility देता है।

इस chapter में हम custom validators को step-by-step, Reactive Forms के perspective से deep में समझेंगे, साथ ही Template-Driven Forms में उनका limited use भी cover करेंगे।

Custom Validator क्या होता है

Custom Validator एक function होता है जो:

  • FormControl या FormGroup को input के रूप में लेता है
  • Validation result return करता है
  • Control की errors property को set करता है

अगर validation pass होती है तो null return किया जाता है।
अगर validation fail होती है तो error object return किया जाता है।

Custom Validator का Basic Structure

Synchronous custom validator का basic structure:

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

export function customValidator(
  control: AbstractControl
): ValidationErrors | null {

  if (/* invalid condition */) {
    return { customError: true };
  }

  return null;
}

Angular internally इस return value के basis पर control को valid या invalid mark करता है।

Simple Custom Validator Example

मान लेते हैं कि username में spaces allow नहीं हैं।

Validator Function

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

export function noSpaceValidator(
  control: AbstractControl
): ValidationErrors | null {

  if (!control.value) {
    return null;
  }

  const hasSpace = control.value.includes(' ');
  return hasSpace ? { noSpace: true } : null;
}

Reactive Form में Use करना

import { FormControl } from '@angular/forms';
import { noSpaceValidator } from './no-space.validator';

username = new FormControl('', [noSpaceValidator]);

Template में Error Show करना

<div *ngIf="username.errors?.['noSpace']">
  Spaces are not allowed
</div>

Validators के Error Object को समझना

Error object का structure fully developer-controlled होता है।

return {
  passwordStrength: {
    minLength: 8,
    hasNumber: false
  }
};

Template में access:

<div *ngIf="control.errors?.['passwordStrength']">
  Weak password
</div>

यह flexibility complex error messages बनाने में बहुत useful है।

Parameterized Custom Validators

अक्सर validator को parameters की जरूरत होती है।

Example: minimum age validator।

Validator Factory Function

export function minAgeValidator(minAge: number) {
  return (control: AbstractControl): ValidationErrors | null => {

    if (!control.value) {
      return null;
    }

    return control.value < minAge
      ? { minAge: { requiredAge: minAge } }
      : null;
  };
}

Use in FormControl

age = new FormControl('', [minAgeValidator(18)]);

Error Message

<div *ngIf="age.errors?.['minAge']">
  Minimum age is {{ age.errors?.['minAge'].requiredAge }}
</div>

FormGroup Level Custom Validators

कुछ validations एक single field पर नहीं, बल्कि multiple fields पर depend करती हैं।

Example: password और confirm password match validation।

Group Validator Function

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

export function passwordMatchValidator(
  group: AbstractControl
): ValidationErrors | null {

  const password = group.get('password')?.value;
  const confirm = group.get('confirmPassword')?.value;

  if (password !== confirm) {
    return { passwordMismatch: true };
  }

  return null;
}

Apply करना FormGroup पर

this.form = this.fb.group(
  {
    password: [''],
    confirmPassword: ['']
  },
  { validators: passwordMatchValidator }
);

Template में Check करना

<div *ngIf="form.errors?.['passwordMismatch']">
  Passwords do not match
</div>

Control vs Group Validator Difference

  • Control validator → single input logic
  • Group validator → multiple inputs dependency

Wrong level पर validator लगाने से validation work नहीं करती, यह beginners की common mistake है।

Asynchronous Custom Validators

जब validation server call या async operation पर depend करती है, तब async validators use किए जाते हैं।

Example: username availability check।

Async Validator Function

import { AbstractControl, ValidationErrors } from '@angular/forms';
import { Observable, of } from 'rxjs';
import { delay, map } from 'rxjs/operators';

export function usernameTakenValidator(
  control: AbstractControl
): Observable<ValidationErrors | null> {

  if (!control.value) {
    return of(null);
  }

  return of(control.value).pipe(
    delay(1000),
    map(value =>
      value === 'admin' ? { usernameTaken: true } : null
    )
  );
}

Apply Async Validator

username = new FormControl(
  '',
  [],
  [usernameTakenValidator]
);

Angular automatically async validator की lifecycle handle करता है।

Async Validation States

Async validators के दौरान control state:

  • pending → validation in progress
  • valid / invalid → result after completion

Template example:

<div *ngIf="username.pending">
  Checking availability...
</div>

Template-Driven Forms में Custom Validators

Template-driven forms में custom validators directive के रूप में बनते हैं।

High-level concept:

  • Validator interface implement करना
  • NG_VALIDATORS provide करना

यह approach ज्यादा boilerplate-heavy होती है, इसलिए complex validation के लिए Reactive Forms recommended हैं।

Reusable Validator Strategy

Large projects में validators को organize करना जरूरी है।

Best practices:

  • Validators को separate files में रखें
  • Domain-specific validators group करें
  • Naming clear और consistent रखें
  • Validators में UI logic न डालें

Example structure:

  • validators/
    • password.validators.ts
    • user.validators.ts

Common Mistakes

  • Validator में side effects करना
  • Direct DOM access
  • Validation logic template में लिखना
  • Async validator को sync की तरह treat करना
  • Group-level validation को control पर apply करना

Custom Validators क्यों जरूरी हैं

Angular Custom Validators आपको:

  • Business rules enforce करने देते हैं
  • Clean और reusable validation logic देते हैं
  • Forms को production-ready बनाते हैं
  • Backend validation के साथ align करते हैं

Custom Validators Angular Forms का सबसे powerful हिस्सा हैं। अगले chapter में हम Dynamic Forms को cover करेंगे, जहाँ validators dynamically add और remove करना एक core requirement बन जाता है।