Angular  

How to Use Angular Forms (Template-Driven vs Reactive Forms)

Introduction

Forms are an essential part of most applications. Whether you are building a login screen, registration form, profile update, or payment form, collecting user input correctly and validating it matters.

Angular provides two powerful approaches to manage forms:

  1. Template-Driven Forms

  2. Reactive Forms

Both allow you to capture input, apply validation, display errors, and submit data. But they are designed for different use cases.

In this article, we will understand:

  • How both form types work

  • When to choose which approach

  • Real-world use cases

  • A complete working example of both forms

  • Best practices and common mistakes

Real-World Scenario

Imagine you are building a small user onboarding module in an Angular application. The flow includes:

  • A simple newsletter signup (just name + email)

  • A detailed user registration form (address, phone number, nested objects, custom validations)

For the small signup form, using Template-Driven makes more sense because it is quick and requires less code.

For the detailed registration form with multiple validations and conditions, Reactive Forms are a better choice because they offer more structure and control.

Approach 1: Template-Driven Forms

Template-Driven Forms are easier to start with and heavily rely on the HTML template. Suitable for smaller and simpler forms.

Step 1: Import FormsModule

In app.module.ts:

import { FormsModule } from '@angular/forms';

@NgModule({
  imports: [BrowserModule, FormsModule],
})
export class AppModule {}

Step 2: Create Component

export class SignupComponent {
  user = {
    name: '',
    email: ''
  };

  submitForm() {
    console.log(this.user);
  }
}

Step 3: Create Form Template

<form #signupForm="ngForm" (ngSubmit)="submitForm()">
  <label>Name:</label>
  <input type="text" name="name" [(ngModel)]="user.name" required />

  <label>Email:</label>
  <input type="email" name="email" [(ngModel)]="user.email" required />

  <button type="submit" [disabled]="signupForm.invalid">Submit</button>
</form>

How Validation Works

Angular automatically tracks:

  • Valid

  • Invalid

  • Touched

  • Dirty

Example validation state

<p *ngIf="signupForm.controls['email']?.invalid && signupForm.controls['email']?.touched">
  Email is required.
</p>

When to Use Template-Driven Forms

Use when:

  • Form is simple

  • Few validations

  • Faster development required

  • No dynamic form generation needed

Example use cases

  • Contact forms

  • Newsletter signup

  • Feedback form

Approach 2: Reactive Forms

Reactive Forms move responsibility to TypeScript. They offer more control, scalability, and testability.

Perfect for:

  • Complex validation

  • Conditional fields

  • Dynamic forms

  • Enterprise applications

Step 1: Import ReactiveFormsModule

In app.module.ts:

import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [BrowserModule, ReactiveFormsModule],
})
export class AppModule {}

Step 2: Create Component with FormGroup

import { FormGroup, FormControl, Validators } from '@angular/forms';

export class RegisterComponent {
  registerForm = new FormGroup({
    fullName: new FormControl('', Validators.required),
    email: new FormControl('', [Validators.required, Validators.email]),
    phone: new FormControl('', Validators.required)
  });

  submitForm() {
    console.log(this.registerForm.value);
  }
}

Step 3: Create Template

<form [formGroup]="registerForm" (ngSubmit)="submitForm()">

  <label>Full Name:</label>
  <input type="text" formControlName="fullName" />
  <span *ngIf="registerForm.get('fullName')?.invalid && registerForm.get('fullName')?.touched">
    Name is required.
  </span>

  <label>Email:</label>
  <input type="email" formControlName="email" />
  <span *ngIf="registerForm.get('email')?.invalid && registerForm.get('email')?.touched">
    Enter valid email.
  </span>

  <label>Phone:</label>
  <input type="tel" formControlName="phone" />

  <button type="submit" [disabled]="registerForm.invalid">Register</button>
</form>

Workflow Diagram

User Input
    |
    V
Form Controls Track State
    |
    +--> Apply Validation Rules
    |
    +--> Update UI Error messages
    |
Form Submission

Comparison Summary

FeatureTemplate-DrivenReactive
SetupEasyMore Setup
Where logic livesMostly TemplateMostly TypeScript
ValidationSimpleAdvanced
ScalabilityLowHigh
Dynamic fieldsHardEasy
Best forSmall appsEnterprise apps

Common Mistakes and Fixes

MistakeWhy it HappensFix
Form values not updatingMissing ngModelAdd two-way binding
Validation not workingWrong form control bindingEnsure formControlName matches
Submit button not disablingNot checking form.invalidUse [disabled]="form.invalid"

Best Practices

  • Use Template-Driven for forms with less than 5 fields.

  • Use Reactive Forms if:

    • There are conditional validations

    • The form grows over time

    • Values must be tracked programmatically

  • Keep validation messages clear and visible.

  • Avoid mixing both approaches in the same form.

Conclusion

Forms are one of the most frequently used features in Angular applications. Knowing both Template-Driven and Reactive Forms gives you flexibility depending on the scale and complexity.

Template-Driven Forms focus on simplicity and quick development. Reactive Forms offer structure, testability, and scalability.

If you continue building large applications, eventually Reactive Forms become the standard.