intermediate18 min

Reactive Forms

Building a typed form with FormGroup and FormControl, and checking validity.

What you'll learn

  • Build a simple reactive form with FormGroup and FormControl
  • Apply a built-in validator to a FormControl
  • Check a form control's validity, guarding against a missing control name

Explanation

Reactive forms model a form's state explicitly in TypeScript rather than relying purely on template directives. A FormGroup bundles named FormControls: this.form = new FormGroup({ email: new FormControl("", [Validators.required, Validators.email]) }). Each FormControl tracks its own value and validity, and built-in validators like Validators.required/Validators.email run automatically as the value changes.

You check a control's validity with this.form.get("email")?.valid (note the ?. -- get() can return null if the control name doesn't exist, so this combines directly with the null-safety-style patterns you've likely seen in other statically-typed languages).

Reactive forms are generally preferred over the alternative (template-driven forms) for anything beyond a trivial form, since the validation logic lives in testable TypeScript rather than being spread across template attributes -- you can unit-test a reactive form's validation rules directly, without rendering any HTML at all.

Guided lab

Fill in the blank: checking a FormControl's validity

AngularNot executed
This lab does not run in your browser or on VisaSparkSchools's servers. Read the code, fill in the missing piece, then reveal the completed code and its expected output.

Fill in the missing safe-navigation operator, then predict the output.

interface SimpleControl {
  value: string;
  valid: boolean;
}

class SimpleFormGroup {
  private controls: Record<string, SimpleControl> = {
    email: { value: "not-an-email", valid: false },
  };

  get(name: string): SimpleControl | null {
    return this.controls[name] ?? null;
  }
}

const form = new SimpleFormGroup();
console.log(form.get("email")____.valid);
console.log(form.get("missing")____.valid);

Stuck? Get a hint.

Common mistakes

  • Forgetting a FormGroup's get() method can return null for an unknown control name, and not guarding against it.
  • Applying validators only in the template (for a reactive form) instead of in the FormControl definition itself, splitting validation logic across two places.
  • Assuming a FormControl's value is automatically trimmed/sanitized -- validators check the raw value; any cleanup is the developer's responsibility.

Knowledge check

Knowledge check

1. What does a FormGroup bundle together?
2. Why might `this.form.get('email')` need a `?.` before accessing `.valid`?
3. Why are reactive forms generally preferred for anything beyond a trivial form?

Takeaway

Reactive forms model validation state explicitly with FormGroup/FormControl in TypeScript, checked via get(name)?.valid to safely guard a missing control.

Summary

FormGroup bundles named FormControls with built-in validators; get(name)?.valid safely checks validity, guarding against an unknown control name.

References

Your notes

Notes save automatically.

Finished this lesson?

Mark it complete to track your progress and schedule a future review.

Next: The Angular Router