Forms

Basic form data management

Forms in Angular (10 minutes)

Reactive Forms

Reactive Forms provide a model-driven approach to handling form inputs and validation. They are more robust, scalable, and testable than template-driven forms.

Setup

First, import ReactiveFormsModule in your module:

// app.module.ts
import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [
    BrowserModule,
    ReactiveFormsModule  // Add this
  ],
  // ...
})
export class AppModule { }

Basic Example

Here’s a simple form with a “Name” input that logs to console on submit:

// name-form.component.ts
import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';

@Component({
  selector: 'app-name-form',
  template: `
    <form [formGroup]="form" (ngSubmit)="onSubmit()">
      <div>
        <label for="name">Name:</label>
        <input id="name" type="text" formControlName="name">
      </div>
      <button type="submit">Submit</button>
    </form>
  `
})
export class NameFormComponent {
  form = new FormGroup({
    name: new FormControl('')  // Initialize with empty string
  });

  onSubmit() {
    console.log(this.form.value);  // Logs: { name: 'whatever user typed' }
  }
}

Comparison with Template-driven Forms

Reactive Forms (FormGroup/FormControl)

  • Model-driven approach
  • More scalable for complex forms
  • Better for form validation
  • Easier to test
  • Synchronous data flow
  • Better type safety

Template-driven Forms (ngModel)

  • Simpler for basic forms
  • Similar to AngularJS
  • Asynchronous data flow
  • More magical (less explicit)

Adding Form Controls

To add more fields, simply add new FormControl instances to your FormGroup:

form = new FormGroup({
  name: new FormControl(''),
  email: new FormControl('')  // Adding email field
});

Corresponding template:

<form [formGroup]="form" (ngSubmit)="onSubmit()">
  <div>
    <label for="name">Name:</label>
    <input id="name" type="text" formControlName="name">
  </div>
  <div>
    <label for="email">Email:</label>
    <input id="email" type="email" formControlName="email">
  </div>
  <button type="submit">Submit</button>
</form>

Form Validation

You can add validators to your form controls:

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

form = new FormGroup({
  name: new FormControl('', Validators.required),
  email: new FormControl('', [
    Validators.required,
    Validators.email
  ])
});

Check validation status:

<div *ngIf="form.get('email')?.errors?.['required']">
  Email is required
</div>
<div *ngIf="form.get('email')?.errors?.['email']">
  Please enter a valid email
</div>

Evaluation Question

Q: “How do you add an ‘Email’ input to this form?”

A: To add an email input:

  1. Add the FormControl to your FormGroup:
form = new FormGroup({
  name: new FormControl(''),
  email: new FormControl('')  // Add this line
});
  1. Add the input to your template:
<div>
  <label for="email">Email:</label>
  <input id="email" type="email" formControlName="email">
</div>
  1. Optional: Add validation:
email: new FormControl('', [
  Validators.required,
  Validators.email
])

Best Practices

  1. Always use Reactive Forms for complex forms
  2. Group related fields using nested FormGroups
  3. Add proper validation with error messages
  4. Use typed forms (Angular 14+) for better type safety
  5. Handle form submission with proper error handling
  6. Use form builders for cleaner code:
constructor(private fb: FormBuilder) {
  this.form = this.fb.group({
    name: [''],
    email: ['']
  });
}

Last modified March 27, 2025: Edit members.yaml (21070ed)