All topics
Formsadvanced

Async Validators

Explain how async validators handle validation rules that require a server round-trip, like checking username uniqueness.

Some validation rules can't be checked synchronously with local data alone — the canonical example is checking whether a username or email is already taken, which requires an HTTP call to the server. An AsyncValidatorFn handles this: instead of returning ValidationErrors | null directly, it returns an Observable<ValidationErrors | null> or Promise<ValidationErrors | null>, and Angular marks the control's status as PENDING while waiting for that Observable/Promise to resolve.

A synchronous validator is like checking a rule against a printed reference card in your pocket — instant. An async validator is like having to call the head office to confirm something — you mark the form 'pending' while you're on hold, and you don't want a slow, outdated call finally connecting and overriding an answer you already got from a faster, more recent call.

Key Concepts

1
A critical interview-relevant detail is debouncing: async validators typically run on every keystroke by default (since they're wired into the same value-change validation cycle as synchronous validators), which would fire an HTTP request on every character typed into a username field without additional care — the idiomatic fix is combining the validator with RxJS operators like debounceTime and distinctUntilChanged, or configuring the control's updateOn: 'blur' option so validation only runs when the field loses focus rather than on every keystroke.
debounceTimedistinctUntilChangedupdateOn: 'blur'
2
Async validators are registered as the third constructor argument to FormControl (synchronous validators are the second), and like synchronous validators, they can be composed — a control can have multiple async validators, all of which must resolve to null for the control to be considered valid, with the control remaining in the PENDING state until every async validator has resolved.
FormControlnullPENDING
3
A thoughtful interview answer also flags cancellation: because async validators commonly wrap switchMap-style HTTP calls internally, a properly implemented one should cancel any in-flight request if the control's value changes again before the previous request resolves, to avoid a slow, stale response incorrectly marking a control valid or invalid after the user has already moved on.
switchMap