Angular17 min read

Reactive Forms: Async Validators (Email Uniqueness)

Validate input using an API call, like checking if an email is already taken.

Liam Turner
December 21, 2025
0.0k0

Async validators are perfect when validation depends on server data. Example: - email already exists - username already taken - coupon code valid ## Step 1: Create an async validator ```ts import { AbstractControl, AsyncValidatorFn } from '@angular/forms'; import { debounceTime, map, of, switchMap } from 'rxjs'; import { inject } from '@angular/core'; import { UsersApi } from './users.api'; export const emailAvailableValidator = (): AsyncValidatorFn => { const api = inject(UsersApi); return (control: AbstractControl) => { if (!control.value) return of(null); return of(control.value).pipe( debounceTime(400), switchMap(email => api.checkEmail(email)), map(res => (res.available ? null : { emailTaken: true })) ); }; }; ``` Assume backend returns: `{ available: true | false }` ## Step 2: Use it on a control ```ts email: new FormControl('', { nonNullable: true, validators: [Validators.required, Validators.email], asyncValidators: [emailAvailableValidator()], }) ``` ## Step 3: Show message in UI ```html <div *ngIf="form.controls.email.errors?.['emailTaken']"> This email is already registered. </div> ``` ## Important performance tip Always debounce async validators, otherwise you spam the API on every keystroke. > Next: Custom form controls with ControlValueAccessor.

#Angular#Forms#Advanced