Reactive Form Validations in Angular

Learn via video courses
Topics Covered

Overview

The form is the heart of the data-centric application. These form assists to feed in data into the system. Also while developing such applications we have to make sure they are secure enough, along with that these pages should have a good user experience. Majorly we have to validate each input field with appropriate validation. We should not allow users to add malicious stuff easily. Validation can help to make user expectations clear, and also can disallow malicious content to feed into the system.

Introduction to Angular Form Validation

Inside Angular reactive forms, validation can be applied in various ways

  1. Built-in validators
  2. Custom validators
  3. Custom validators with the directive

Built-in Validators

ValidatorTypeDescription
minnumbermin number that should be provided
maxnumbermax number that should be provided
requiredcontrol should have value
requiredTruecontrol that should have the value true
emailstring that matches valid email pattern
minLengthnumberstring that of minimum length
maxLengthnumberstring that of maximum length
patternstring or RegExpstring should match a pattern
nullValidatorvalidator that return nothing
composeValidationFn[]Can create a new validator by combining multiple
composeAsyncValidationFn[]Can create a new validator by combining multiple asynchronously

Validations can be applied on a FormControl.

For eg. suppose we wanted to apply required validation over an email field. The code would look like below

app.component.ts

app.component.html

app.module.ts

Understand the above code stepwise

  1. First we create a FormControl instance using new FormControl(...)
  2. Then we pass parameters to FormControl class.
  3. 1st parameter is the default value.
  4. the second parameter would be an array of ValidationFn.
  5. In the above code we use email and required validators from Validators
  6. Don't forget to add ReactiveFormsModule to use form reactive features.

The previous example was just a small warm-up. We can take an example of a User edit form that has to have the below validations.

  1. Full Name
    • required
    • min length 6 characters
    • max length 20 characters
  2. Email
    • required
    • email
  3. Street -
    • required
    • max length 20 characters
  4. City -
    • required
  5. Zip -
    • required
    • number

app.component.ts

app.component.html

demo

build in validators demo

So far we have seen that we added a validator on each field. Once all field validation criteria are fulfilled, the "Save" button is enabled. And click of the save button prints the userForm object in the console.

userform object example

We can see userForm contains controls, and those controls maintain their control level state, like valid, invalid, errors, touched, etc. Also, it is mandatory that we should let the user know what went wrong with validations. We can utilize these userForm objects to apply validations. We can add these validation messages under all fields.

We can access field-level errors by navigating between userForm FormGroup instances like

userForm -> controls -> name -> errors.

Then we can keep eye on relevant errors property like required, email, min, max, etc. Similar we did on line:6-10.

Building a Custom Validator

We can either use built-in validators or create a custom validator that can be used to fulfill the business need. All built-in validators go under the Validators class. But to create a custom validator, we have to extend the Validator class, it looks like below.

By following the above method interface, we should return ValidationFn.

We can replace the email field validator with the validateEmailId custom validator. It will perform customized validation over the email field.

Building Custom Validator Directives

We can extend this validator to be used declaratively. We can create a directive that can act as a validator on the provided field.

This directive can be used on the ngModel / formControlName input field as the selector is combined with the validateEmailId attribute. It will perform the same validation as we did before, but now we made it declaratively mentioned over the HTML.

Custom Validators with Dependencies

We had to create a factory function validateEmailFactory that would accept email blackList. And then we would add an additional check inside the validator function. The factory function should return the same ValidationFn as we did before.

Inside a directive factory function, we passed the blockedList computed from EmailService's getBlockedEmailList method. To use dependency on the provider level, we could use deps: [EmailService] option.

To display the block list email error we've used *ngIf="emailErrors.blackListed" condition.

demo

custom validators with dependencies demo

Conclusion

  • How to perform validation on reactive form
  • How to create a custom validator for a custom requirement.
  • How to use the custom validator declaratively
  • How to register a custom validator with dependency.