Data & FormsPro· 45 min read

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:

  1. You show a <form> with one or more inputs (a name box, an email box, and so on).
  2. The user types into the inputs. Angular keeps each typed value linked to your class (via ngModel in template-driven forms, or a FormControl in reactive forms).
  3. The user presses the submit button.
  4. That fires the form’s (ngSubmit) event, which runs your method (here called save()).
  5. Inside that method you read the values the user typed (from a property like title, or from form.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.

A small template-driven form
<!-- 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.

The form is defined in TypeScript
// 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.

The template connects to the form group
<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-drivenReactive
Defined inThe HTML templateThe TypeScript class
Best forSmall, simple formsLarge, complex forms
Needs moduleFormsModuleReactiveFormsModule
TestingHarderEasier

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?

Answer: Reactive forms are built in the class with FormGroup/FormControl, then linked to the template — giving more control and easier testing.

✍️ Practice

  1. Build a template-driven form with ngModel that shows what the user typed live.
  2. Build a reactive form with two fields and log form.value on submit.

🏠 Homework

  1. Create a sign-up form (name and email) as a reactive form and display the form’s value object below it.
Want to learn this with a mentor?

CodingClave runs guided, project-based training (28-day, 45-day & 6-month batches).

Explore Training →