π Reactive & Template Forms
FormBuilder, FormGroup, FormControl, custom validators, and FormArray for dynamic inputs.
Template-Driven vs Reactive Forms
Angular offers two choices for form management based on complexity and testability.
| Feature | Template-Driven Forms | Reactive Forms |
|---|---|---|
| Setup | Implicit in HTML template via ngModel | Explicit in TypeScript class using FormBuilder |
| Data Model | Unstructured & Mutable | Structured & Immutable |
| Validation | HTML Directives (required, minlength) | TypeScript functions (Validators.required) |
| Scalability | Best for simple forms / dialogs | Best for complex, dynamic, highly tested forms |
Building Reactive Forms
Use `FormBuilder` to create strong typed form groups and controls.
register.component.ts
TypeScript
import { Component, inject } from '@angular/core'; import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; @Component({ selector: 'app-register', standalone: true, imports: [ReactiveFormsModule], templateUrl: './register.component.html' }) export class RegisterComponent { private fb = inject(FormBuilder); regForm = this.fb.group({ username: ['', [Validators.required, Validators.minLength(3)]], email: ['', [Validators.required, Validators.email]], password: ['', [Validators.required, Validators.minLength(6)]] }); onSubmit() { if (this.regForm.valid) { console.log('Form Data:', this.regForm.value); } } }
Form Validation in HTML Template
Bind `[formGroup]` and `formControlName` in HTML templates to show instant validation feedback.
register.component.html
HTML
<form [formGroup]="regForm" (ngSubmit)="onSubmit()">
<label>Username:</label>
<input formControlName="username" />
<div *ngIf="regForm.get('username')?.invalid && regForm.get('username')?.touched" class="error">
Username is required (min 3 chars).
</div>
<button type="submit" [disabled]="regForm.invalid">Register</button>
</form>
FormArray for Dynamic Input Fields
Use `FormArray` when users need to add or remove dynamic inputs (e.g. multiple phone numbers).
dynamic-form.ts
TypeScript
get phones(): FormArray { return this.regForm.get('phones') as FormArray; } addPhone() { this.phones.push(this.fb.control('', Validators.required)); }