Skip to main content

Template-Driven Forms

How it works

Browser's default form behavior

By default — without importing FormsModule — forms keep the default behavior of the HTML form elements.
In other words, they will generally submit and cause a page reload.

The main building blocks for Template-Driven Forms are:

  • FormsModule
  • ngModel directive

1. Import the FormsModule

The first step is to import the FormsModule in each component using the <form> tag or the ngModel directive.

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

@Component({
...
imports: [FormsModule],
template: `<form>...</form>`
})
class RecipeForm {}

Then you can start using the ngModel directive to bind any signal — or property if you really have to — to a form control (e.g. input).

@Component({
...
template: `
<form>
<input type="text" name="name" [(ngModel)]="title" />
</form>
<hr>
<p>Title: {{ title() }}</p>
`
})
class RecipeForm {
protected readonly title = signal<string | null>(null);
}

2. Bind the ngModel directive to the form control

Whenever the input changes, it will update the title signal, and propage the changes in the application.

[(ngModel)] is a shorthand for [ngModel] and (ngModelChange)

Whenever a component has an output with the same name as the input and the Change suffix, two-way binding (i.e. [()] banana in a box) shorthand becomes possible.

In this specific case:

  • [ngModel] is used to bind the value of the input to the title signal.
  • (ngModelChange) is used to update the title signal when the input changes.
<input type="text" name="name" [ngModel]="title()" (ngModelChange)="title.set($event)" />

3. Add a submit event listener

@Component({
...
template: `
<form (ngSubmit)="createRecipe()">
<input type="text" name="name" [(ngModel)]="title" />
<button type="submit">Submit</button>
</form>
<hr>
<p>Title: {{ title() }}</p>
`
})
class RecipeForm {
protected readonly title = signal<string | null>(null);

createRecipe() {
console.log('creating recipe with title:', this.title());
...
}
}
Prefer ngSubmit to submit

While things might seem to work well with submit event, it is better to use ngSubmit as they are not triggered exactly at the same time.
Angular listens to submit events and triggers the ngSubmit after doing some important internal work such as updating the model.

Additional Resources

Pragmatic Angular Testing
👨🏻‍🍳 Let's cook some tests →

💰 80€ · 170€ · Lifetime access

Learn how to write reliable tests that survive upgrades and refactorings.