August 6, 2026
Angular form validation step by step tutorial

Angular Form Validation Tutorial (2026 Edition)

Updated for Angular 19 — June 29, 2026 · Built-in and custom validators, error messages, and reactive form validation. All Angular tutorials

Complete guide: Angular Reactive Forms Validation — Complete Guide (2026)

Kindson Munonye · Software engineer & technical author
GitHub · LinkedIn · About · YouTube
Last updated by Kindson Munonye — June 29, 2026


📚 Tutorial hub: Angular tutorials · CRUD series

Related: Template-driven forms · Reactive forms

Prerequisites: Reactive forms tutorial recommended.

Estimated time: ~40 minutes · Last updated: June 29, 2026

Try it live: Open StackBlitz demo (editable Angular sandbox)

📚 Browse all tutorials: Angular tutorials hub

This simple article explains form validation in Angular. You’ll also learn how to display messages to the user based on validation errors.

This tutorial would be step by step.

  1. About HTML Form Validation
  2. Setup the Form
  3. Submit Function
  4. Validation Styles
  5. Validation Messages
  6. More on Validation

 

1. Native HTML Form Validation

Without Angular, we have a native HTML form validation. You can decide to use in your angular application. One benefit is that it is very easy to use.

To use the native HTML form validation, just include ngNativeValidation to the form tag. Then any validation markup would be handled. For example including required to the input would cause a required field validation.

 

2. Set up Your Form

I have setup a basic html form. This is shown below.

<form #f="ngForm" (ngSubmit)="onSubmit(f)">
  <div class="form-group">
    <label>Firstname</label>
    <div class="input-group">
      <input class="form-control" name="firstname" required>
    </div>
  </div>
  <div class="form-group">
    <label>Lastname</label>
    <div class="input-group">
      <input name="lastname" class="form-control" ngModel />
    </div>
  </div>
  <div class="form-group">
    <label >Department</label>
    <div class="input-group">
      <input name="department" class="form-control" ngModel>
    </div>
  </div>
  <div class="form-group">
    <label>Email</label>
    <div class="input-group">
      <input name="email" class="form-control" ngModel>
    </div>
  </div>
  <div class="form-group">
    <label for="country">Country</label>
    <div class="input-group">
      <select id="country" name="country" class="form-control" ngModel>
        <option *ngFor="let country of countries" value={{country}}>
          {{country}}
        </option>
      </select>
    </div>
  </div>
  <div class="border text-center">
    <button type="submit" data-dismiss="modal" class="btn btn-info">Submit</button>
  </div>
</form>
</div>

 

Note the tree attributes for each control. For firstname, for instance:

  • name = “firstname” – requirement for using ngModel
  • NgModel – creates a binding with the model
  • #firstname = ngModel : helps us get the value of the particular control

Like this

name="firstname" #firstname="ngModel" ngModel

Do this for all the other controls.

Note: It’s easy to confuse NgModel with ngModel. So beware!

 

3. Write the Submit function

Unlike native html validation, the Angular validation would execute the submit function regardless of whether the form entries are valid or not. However, you can easily check the form for validity before executing the actual submit code.

The onSubmit() function below does this.

  onSubmit(f: NgForm) {
   if (f.valid) {
     this.message = 'The form is VALID';
   }
   if (f.invalid){
     this.message = 'The form is INVALID';
   }
  }

 

4. Valid and Invalid Styles

Now we would like to add a style for the inputs based on if it is valid. This style is shown below. But you can modify it as you wish.

input.ng-invalid{
  border-left: 5px solid red;
}

input.ng-valid{
  border-left: 5px solid green;
}

So now, if you test out the application, you’ll see that if the field are empty, invalid style is applied. And vice versa.

 

5. Validation Messages

Now we would like to display validation message if an invalid input is detected.

You can add  a message for each control. Or you can add a general message for all the controls.

So go ahead to add a <span></span> tag after the firstname. Give this a class, say, error.

<span *ngIf="firstname.invalid" class="error">You must enter firstname</span>

 

Then define the error class.

.error{
  color: red;
}

 

Touched and Untouched

To prevent display of the error message when page reload, add this condition to the *ngIf:

*ngIf="firstname.invalid && firstname.touched"

 

6. Min, Max, and Pattern Validators

For numeric fields, use Validators.min() and Validators.max(). For pattern matching (letters only, phone format), use Validators.pattern():

phone: ['', [Validators.required, Validators.pattern(/^\d{10}$/)]],
username: ['', [Validators.required, Validators.pattern(/^[a-zA-Z]+$/)]]

7. Email and Password Validation

email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(8)]],
confirmPassword: ['', Validators.required]

For password confirmation, use a cross-field validator on the FormGroup:

function passwordMatch(group: AbstractControl): ValidationErrors | null {{
  const pass = group.get('password')?.value;
  const confirm = group.get('confirmPassword')?.value;
  return pass === confirm ? null : {{ passwordMismatch: true }};
}}

this.form = this.fb.group({{ password: [''], confirmPassword: [''] }}, {{ validators: passwordMatch }});

8. Custom Validators (Complete Example)

Custom validators are functions that return null (valid) or an error object:

export function forbiddenName(name: string): ValidatorFn {{
  return (control: AbstractControl): ValidationErrors | null => {{
    return control.value === name ? {{ forbiddenName: {{ value: control.value }} }} : null;
  }};
}}

// Apply to control
firstname: ['', [Validators.required, forbiddenName('admin')]]

Display custom errors in the template:

<span *ngIf="firstname.hasError('forbiddenName')">That name is not allowed</span>

9. Validation in Reactive Forms

The same validators work identically in reactive forms. Access the form with formControlName and check .errors on each control. Use markAllAsTouched() on submit to reveal all messages at once.

Practice: Fork the StackBlitz validation demo and add your own custom validator.




Kindson Munonye

Kindson Munonye is a software engineer and technical author specializing in Angular, Spring Boot, and microservices architecture. He publishes step-by-step tutorials with source code covering CRUD operations, reactive forms, CQRS, event sourcing, and REST API integration.GitHub · LinkedIn · About · YouTube

View all posts by Kindson Munonye →
5 1 vote
Article Rating
Subscribe
Notify of
guest
5 Comments
Oldest
Newest Most Voted
trackback

[…] can be a bit more creative with validation by displaying nicer styles like shown below. See my Validation Tutorial and step by step […]

trackback

[…] Continue the series: Part 2: Reactive Forms · Form validation guide […]

trackback

[…] Continue the series: Part 1: Template-driven forms · Form validation guide […]

Porn IP
Porn IP
1 month ago

Every day is a new beginning