Written by: Geoffrey Callaghan

Angular Forms Validation

Angular Forms Validation

Angular forms validation is a powerful feature that ensures the data entered into forms is accurate and meets the specified criteria. Angular provides two main approaches for form validation: template-driven forms and reactive forms. Each approach offers different mechanisms and levels of control.

Template-Driven Forms Validation

Template-driven forms are simple and use Angular directives to handle validation in templates.

Basic Example

Here’s a basic example of a template-driven form with validation:

<form #myForm="ngForm" (ngSubmit)="onSubmit(myForm)">
  <div>
    <label for="name">Name</label>
    <input type="text" id="name" name="name" ngModel required>
    <div *ngIf="myForm.submitted && myForm.controls['name'].invalid">
      Name is required.
    </div>
  </div>
  <button type="submit">Submit</button>
</form>

In this example:

  • The required attribute adds the required validation rule.
  • The *ngIf directive displays an error message if the form is submitted and the name field is invalid.

Common Validators

  • required
  • minlength
  • maxlength
  • pattern

Reactive Forms Validation

Reactive forms are more powerful and give more control over the form and its validation. They are defined in the component class.

Basic Example

Here’s how you can create a reactive form with validation:

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-reactive-form',
  template: `
    <form [formGroup]="form" (ngSubmit)="onSubmit()">
      <div>
        <label for="name">Name</label>
        <input id="name" formControlName="name">
        <div *ngIf="form.controls['name'].touched && form.controls['name'].invalid">
          <small *ngIf="form.controls['name'].errors?.required">Name is required.</small>
          <small *ngIf="form.controls['name'].errors?.minlength">Name must be at least 3 characters long.</small>
        </div>
      </div>
      <button type="submit" [disabled]="form.invalid">Submit</button>
    </form>
  `
})
export class ReactiveFormComponent {
  form: FormGroup;

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      name: ['', [Validators.required, Validators.minLength(3)]]
    });
  }

  onSubmit() {
    if (this.form.valid) {
      console.log(this.form.value);
    }
  }
}

In this example:

  • FormBuilder is used to create the form group and form controls.
  • Validators are added to the form controls for required and minlength validations.
  • The template uses formControlName to bind the input to the form control and conditional error messages are displayed based on the control’s state.

Custom Validators

You can also create custom validators for more complex validation logic.

import { AbstractControl, ValidatorFn } from '@angular/forms';

export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
  return (control: AbstractControl): {[key: string]: any} | null => {
    const forbidden = nameRe.test(control.value);
    return forbidden ? {'forbiddenName': {value: control.value}} : null;
  };
}

// Usage in component
this.form = this.fb.group({
  name: ['', [Validators.required, forbiddenNameValidator(/admin/)]]
});

Summary

Angular forms validation ensures that user input is checked for correctness and completeness. Template-driven forms are straightforward and suitable for simpler use cases, while reactive forms provide more flexibility and control for complex forms. Using built-in validators, custom validators, and conditional error messages, you can create robust forms that provide a good user experience and reliable data.