Skip to main content

Reactive Forms

Reactive Forms are a more programmatic way of defining forms. Therefore, they provide more control and flexibility.

Reactive Forms start with pure TypeScript.

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

@Component(...)
class RecipeForm {
protected readonly titleCtrl = new FormControl<string | null>(null);
}

1. Create a FormControlโ€‹

The FormControl has all sorts of methods and properties that allow you to interact with it. Here are some examples:

class FormControl<T> {
setValue(value: T): void;
value: T;
valueChanges: Observable<T>;
valid: boolean;
dirty: boolean;
...
}

You can then bind the titleCtrl to the UI with formControl directive.

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

@Component({
...
imports: [ReactiveFormsModule],
template: `
<form>
<input type="text" [formControl]="titleCtrl" />
</form>
`
})
class RecipeForm {
protected readonly titleCtrl = new FormControl<string | null>(null);
}

2. Things become more interesting with FormGroup (and friends)โ€‹

You can group multiple FormControls together into a FormGroup.

Form controls are flexible

It is even possible to nest FormGroups inside each other and create dynamic forms.

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

@Component({
...
imports: [ReactiveFormsModule],
template: `
<form [formGroup]="recipeForm">
<input type="text" formControlName="title" />
<input type="text" formControlName="description" />
</form>
`
})
class RecipeForm {
protected readonly recipeForm = new FormGroup({
title: new FormControl<string | null>(null),
description: new FormControl<string | null>(null),
});
}

3. Add a submit event listenerโ€‹

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

@Component({
...
imports: [ReactiveFormsModule],
template: `
<form [formGroup]="recipeForm" (ngSubmit)="createRecipe()">
<input type="text" formControlName="title" />
<input type="text" formControlName="description" />
</form>
`
})
class RecipeForm {
protected readonly recipeForm = new FormGroup({
title: new FormControl<string | null>(null),
description: new FormControl<string | null>(null),
});

createRecipe() {
console.log(this.recipeForm.value);
// ^ { title: 'Babaganoush', description: 'Smoky eggplant dip.' }

this.recipeForm.reset();
}
}
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โ€‹

Younes Jaaidi

~1 email per month. Unsubscribe anytime.

Pragmatic Angular Testing

๐Ÿ’ฐ 170โ‚ฌ โ†’ 80โ‚ฌ ยท Launch Price

Stop rewriting tests every time you refactor.