Forms: Template-Driven & Reactive
Angular gives you two ways to build forms — simple ngModel forms, and powerful reactive forms defined in code.
What you will learn
- Build a template-driven form with ngModel
- Build a reactive form with FormGroup
- Choose the right style for the job
Two roads to a form
Forms are how users send you data. Angular offers two styles, and both are fully supported:
- Template-driven — built mostly in the HTML with
ngModel. Quick and easy; great for small forms. - Reactive — the form is defined in the TypeScript class. More code, but more control and easier to test; great for big forms.
Whichever style you pick, the flow of a form is always the same. Here it is in order, before we look at any code:
- You show a
<form>with one or more inputs (a name box, an email box, and so on). - The user types into the inputs. Angular keeps each typed value linked to your class (via
ngModelin template-driven forms, or aFormControlin reactive forms). - The user presses the submit button.
- That fires the form’s
(ngSubmit)event, which runs your method (here calledsave()). - Inside that method you read the values the user typed (from a property like
title, or fromform.value) and do something with them — show them, save them, or send them to an API.
The two styles below are just two different ways to wire up step 2. Everything else stays identical.
Template-driven form
You already know ngModel. A template-driven form just binds inputs and handles submit in the template.
<!-- needs FormsModule imported -->
<form (ngSubmit)="save()">
<input name="title" [(ngModel)]="title">
<button type="submit">Add</button>
</form>
<p>You typed: {{ title }}</p>Note: Output:
Type “Buy milk” and the line reads “You typed: Buy milk”.
Pressing Add runs save() (via ngSubmit), where you would use the title value. The two-way binding kept title in sync as you typed.
Reactive form
A reactive form lives in the class. You build a FormGroup of FormControl fields, then connect it to the template.
// component class — needs ReactiveFormsModule imported
import { FormGroup, FormControl } from '@angular/forms';
export class TaskFormComponent {
form = new FormGroup({
title: new FormControl(''),
});
save() {
console.log(this.form.value); // { title: 'Buy milk' }
}
}Note: Output:
(No visible output by itself.)
The class builds a FormGroup with one field called title. Nothing shows on screen until the template below connects to this form. save() will later print the field values.
<form [formGroup]="form" (ngSubmit)="save()">
<input formControlName="title">
<button type="submit">Add</button>
</form>Note: Output (console after typing “Buy milk” and submitting):
{ title: ’Buy milk’ }
The class owns the form. form.value gives you a tidy object of all fields at once — easy to send to an API.
| Template-driven | Reactive | |
|---|---|---|
| Defined in | The HTML template | The TypeScript class |
| Best for | Small, simple forms | Large, complex forms |
| Needs module | FormsModule | ReactiveFormsModule |
| Testing | Harder | Easier |
Tip: New to forms or building something tiny? Start template-driven. Building a big form with lots of fields and validation? Reach for reactive forms.
Q. Where is a reactive form mainly defined?
✍️ Practice
- Build a template-driven form with
ngModelthat shows what the user typed live. - Build a reactive form with two fields and log
form.valueon submit.
🏠 Homework
- Create a sign-up form (name and email) as a reactive form and display the form’s value object below it.