BACK
Use casesAsync validation — checking username/email
Use cases · 11

Async validation — checking username/email

Pattern

The user types a username or email, and the server answers: "available" or "already taken." This is async validation — a check that can't pass locally; it needs the server.

The problem it solves

Every keystroke is a potential HTTP request. Without protection you get dozens of requests, and a slow response for alice may arrive AFTER the response for taken and overwrite the field's current state. The form shows "available" when it's really "taken".

Operators and why they matter

  • debounceTime — wait for a pause so we don't hit the server on every letter.
  • distinctUntilChanged — if the value hasn't changed, don't re-check.
  • switchMap — a new request cancels the old one. This is the key to guarding against the response race.
  • catchError inside switchMap — an API error becomes a validation state instead of killing the whole valueChanges stream.
  • map — normalize the server response into an object the form understands.

Gotchas

  • mergeMap instead of switchMap — an old slow response overwrites a new one. The race comes back.
  • exhaustMap is harmful here: while an old check is in flight, new values are ignored — you'll see the status for input that's already been cleared.
  • catchError outside the whole pipeline — the first error ends the entire validation stream, and validation stops working forever.

What you get

The user sees only the result for the last stable value. Network failures are just another field state, not a broken form.

script.ts // TypeScript
CONSOLE · Console output
Hit Run to see the result...