w3resource

Form Validation

Imagine having a web application where data from input forms are never validated, we would have a database where:

  1. The information in a column may be inaccurate.
  2. The application is prone to just about any attack we can think of.
  3. Users are at risk when they submit sensitive data.

Security of web applications includes protecting the forms. A robust web application will need to have its forms validated.

Form validation improves overall data quality by validating user input for accuracy and completeness. Angular makes form validation a breeze and in this tutorial, we will look at how you can implement it in your web page.

Template-driven validation

To add validation to a template-driven form, you add the same validation attributes as you would with native HTML form validation. Angular uses directives to match these attributes with validator functions in the framework.

Every time the value of a form control changes, Angular runs validation and generates either a list of validation errors, which results in an INVALID status or null, which results in a VALID status.

You can then inspect the control's state by exporting ngModel to a local template variable. The following example exports NgModel into a variable called name:

Example:

HTML Code:

<input id="name" name="name" class="form-control"
      required minlength="4" appForbiddenName="bob"
      [(ngModel)]="hero.name" #name="ngModel" >

<div *ngIf="name.invalid && (name.dirty || name.touched)"
    class="alert alert-danger">

  <div *ngIf="name.errors.required">
    Name is required.
  </div>
  <div *ngIf="name.errors.minlength">
    Name must be at least 4 characters long.
  </div>
  <div *ngIf="name.errors.forbiddenName">
    Name cannot be Bob.
  </div>

</div>

Live Demo:

It is just a code snippet explaining a particular concept and may not have any output

See the Pen formvalidation_validateName.html by w3resource (@w3resource) on CodePen.


Note the following:

  • The <input> element carries the HTML validation attributes: required and minlength. It also carries a custom validator directive, forbiddenName. For more information, see Custom validators section.
  • #name="ngModel" exports NgModel into a local variable called name. NgModel mirrors many of the properties of its underlying FormControl instance, so you can use this in the template to check for control states such as valid and dirty. For a full list of control properties, see the AbstractControl API reference.
  • The *ngIf on the <div> element reveals a set of nested message divs but only if the name is invalid and the control is either dirty or touched.
  • Each nested <div> can present a custom message for one of the possible validation errors. There are messages for required, minlength, and forbiddenName.

Reactive form validation

In a reactive form, the source of truth is the component class. Instead of adding validators through attributes in the template, you add validator functions directly to the form control model in the component class. Angular then calls these functions whenever the value of the control changes.

Validator functions

There are two types of validator functions: sync validators and async validators.

  • Sync validators: functions that take a control instance and immediately return either a set of validation errors or null. You can pass these in as the second argument when you instantiate a FormControl.
  • Async validators: functions that take a control instance and return a Promise or Observable that later emits a set of validation errors or null. You can pass these in as the third argument when you instantiate a FormControl.

Note: for performance reasons, Angular only runs async validators if all sync validators pass. Each must complete before errors are set.

Built-in validators

Angular has built-in validators which you can use for form validation. Attributes like required and minlength are available for use as functions from the Validators class.

To update the hero form to be a reactive form, See below:

HTML Code:

<input id="name" class="form-control"
      formControlName="name" required >

<div *ngIf="name.invalid && (name.dirty || name.touched)"
    class="alert alert-danger">

  <div *ngIf="name.errors.required">
    Name is required.
  </div>
  <div *ngIf="name.errors.minlength">
    Name must be at least 4 characters long.
  </div>
  <div *ngIf="name.errors.forbiddenName">
    Name cannot be Bob.
  </div>
</div>

Live Demo:

It is just a code snippet explaining a particular concept and may not have any output

See the Pen reactiveformvalidation.html by w3resource (@w3resource) on CodePen.


Key takeaways:

  • The form no longer exports any directives and instead uses the name getter defined in the component class.
  • The required attribute is still present. While it's not necessary for validation purposes, you may want to keep it in your template for CSS styling or accessibility reasons.

Previous: Template driven forms
Next: Dynamic Forms



Share this Tutorial / Exercise on : Facebook and Twitter