Chapter 9: Forms – Template-driven & Reactive

Forms – Template-driven & Reactive — one of the most practical and frequently used parts of Angular.

In 2026 (with Angular ~21+), forms are in a transitional phase:

  • Template-driven → still fully supported, simple for quick forms, and now works beautifully with signals via [(ngModel)] + signal()
  • Reactive → remains the go-to for complex, validation-heavy, dynamic, or testable forms (enterprise loves it)
  • Signal Forms (experimental / early stable in v21+) → a new third way that unifies everything with signals, reduces boilerplate, and is the future direction (but not yet replacing the classics for most production apps)

As your teacher, I’ll teach you what’s practical today (early 2026):

  • Template-driven with signals (super clean for 70% of forms)
  • Classic reactive forms (still king for complex needs)
  • How signals integrate / bridge the two (using model(), toSignal(), etc.)
  • Quick look at where Signal Forms are heading (so you’re ready when it matures)

We’ll build the same form twice: a registration form (name, email, password, age, terms checkbox).

1. Template-driven Forms + Signals (Modern, Recommended for Simple/Medium Forms)

Why love it in 2026?

  • Minimal code in TS
  • Two-way binding with [(ngModel)] + signal() or model()
  • Validation via directives (required, email, minlength, etc.)
  • Signals make the model reactive → UI auto-updates

Setup

Import FormsModule (not ReactiveFormsModule):

TypeScript

Template (registration.component.html)

HTML

Style tip (add to css):

CSS

Key modern points

  • [(ngModel)]=”name” → two-way bind to signal → read with name() in TS
  • Validation messages with @if + submitted() signal
  • Form-level validity via #regForm=”ngForm” + regForm.valid
  • No FormGroup boilerplate

2. Reactive Forms (Classic + Still Essential for Complex Cases)

Why still use?

  • Dynamic fields (add/remove controls)
  • Cross-field validation
  • Easier unit testing
  • Granular control over async validation, statusChanges, etc.

Setup

Import ReactiveFormsModule:

TypeScript

Component TS

TypeScript

Template

HTML

Bridge to signals (very common hybrid)

TypeScript

3. Signals + Forms Integration Summary (2026 Best Practices)

Scenario Recommended Approach Why / How Signals Fit In
Simple form (login, search) Template-driven + [(ngModel)] + signal() Zero boilerplate, two-way sync automatic, validation via directives + @if
Medium form Template-driven + model() for two-way age = model<number>() → banana-in-box [(age)] in child components too
Complex / dynamic / testable Reactive Forms + toSignal(valueChanges) Keep FormGroup, expose signals for template reactivity (e.g. isDirty = toSignal(form.statusChanges.pipe(map(s => s === ‘INVALID’)))
Future / new projects Try Signal Forms (experimental) form(modelSignal, schema) → unified signals API, auto validation signals, less code

Quick Signal Forms sneak peek (experimental in v21+ — check angular.dev/guide/forms/signals)

TypeScript

→ Then bind with <input [formField]=”loginForm.email” />

But for production in early 2026 → stick to the two classics + signal bridges.

Mini Practice Task

  1. Build the registration form with template-driven + signals (use individual signals)
  2. Add a child component <app-password-strength [password]=”password”></app-password-strength> that shows strength bar (use input() + computed())
  3. Switch to reactive version → add async validator for email uniqueness (fake delay)
  4. Bonus: Use model() in a custom input component for two-way binding

Forms are huge — but once you pick one style + signals, it clicks fast.

Next is usually advanced topics (defer, SSR, state management). Want to go there, or deepen forms (custom validators, async validation, Signal Forms deep dive, form arrays, testing forms)? Tell me — we’re building real apps now! 😄

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *