Chapter 9: Forms in Angular 20 (Standalone Components)
Forms are essential for any Angular application that requires user input, whether it’s a simple contact form or a complex multi-step form. Angular 20 supports two powerful form-building approaches — Template-driven and Reactive forms — both fully compatible with the standalone component architecture. In this chapter, we’ll explore how to build forms, validate inputs, and dynamically generate forms with FormBuilder.
1. Template-driven Forms
Template-driven forms rely heavily on Angular’s directives in the template to create and validate forms. They are simpler and great for small forms.
Setup
Import FormsModule
when bootstrapping your standalone app:
import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, {
providers: [
provideRouter([]),
importProvidersFrom(FormsModule)
]
});
Example: Simple Template-driven Form
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
standalone: true,
selector: 'app-contact-form',
imports: [FormsModule],
template: `
` }) export class ContactFormComponent { onSubmit(form: any) { if (form.valid) { alert(‘Form Submitted successfully!’); } } }
Template-driven forms are easy to set up and validate using directives like ngModel
, required
, and email
. However, they are less scalable for large or dynamic forms.
2. Reactive Forms (FormGroup & Validators)
Reactive forms provide more programmatic control. You define the form model in your component class and bind it to the template. This approach is better for complex and dynamic forms.
Setup
Import ReactiveFormsModule
when bootstrapping:
import { ReactiveFormsModule } from '@angular/forms';
bootstrapApplication(AppComponent, {
providers: [
provideRouter([]),
importProvidersFrom(ReactiveFormsModule)
]
});
Example: Reactive Form with Validation
import { Component } from '@angular/core';
import { ReactiveFormsModule, FormGroup, FormControl, Validators } from '@angular/forms';
@Component({
standalone: true,
selector: 'app-reactive-form',
imports: [ReactiveFormsModule],
template: `
` }) export class ReactiveFormComponent { profileForm = new FormGroup({ firstName: new FormControl(”, Validators.required), email: new FormControl(”, [Validators.required, Validators.email]) }); get firstName() { return this.profileForm.get(‘firstName’)!; } get email() { return this.profileForm.get(’email’)!; } onSubmit() { if (this.profileForm.valid) { alert(‘Reactive Form Submitted!’); console.log(this.profileForm.value); } } }
3. Dynamic Forms and FormBuilder
Reactive forms let you build forms dynamically using FormBuilder — a service that simplifies creating form controls.
Setup with FormBuilder
import { Component } from '@angular/core';
import { ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
standalone: true,
selector: 'app-dynamic-form',
imports: [ReactiveFormsModule],
template: `
` }) export class DynamicFormComponent { form: FormGroup; fields = [ { name: ‘username’, label: ‘Username’ }, { name: ‘password’, label: ‘Password’ }, ]; constructor(private fb: FormBuilder) { this.form = this.fb.group({}); this.fields.forEach(field => { this.form.addControl(field.name, this.fb.control(”, Validators.required)); }); } onSubmit() { if (this.form.valid) { alert(‘Dynamic Form Submitted!’); console.log(this.form.value); } } }
Dynamic forms are perfect when form controls depend on runtime data. Using FormBuilder reduces boilerplate and improves readability.
Summary
- Use template-driven forms for simple, declarative forms with minimal setup.
- Use reactive forms when you need full control, complex validations, or dynamic form construction.
- Standalone components make integrating forms easier by importing
FormsModule
orReactiveFormsModule
directly in components or the bootstrap process.
Next Chapter Preview
In Chapter 10, we’ll dive into HTTP and API Integration using Angular’s HttpClientModule, covering GET, POST, PUT, DELETE requests, and handling errors with interceptors.