DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Rediscovering Angular: Modern Advantages and Technical Stack
  • Angular Input/Output Signals: The New Component Communication
  • Azure Deployment Using FileZilla
  • Angular RxJS Unleashed: Supercharge Your App With Reactive Operators

Trending

  • Scaling Mobile App Performance: How We Cut Screen Load Time From 8s to 2s
  • Analyzing “java.lang.OutOfMemoryError: Failed to create a thread” Error
  • Enhancing Security With ZTNA in Hybrid and Multi-Cloud Deployments
  • Understanding and Mitigating IP Spoofing Attacks
  1. DZone
  2. Coding
  3. Frameworks
  4. How to Create Custom Validators in Angular

How to Create Custom Validators in Angular

In this post, we look at how to create the functionality that tells your user if they've entered in their information correctly. But, you know, in a nice way.

By 
Dhananjay Kumar user avatar
Dhananjay Kumar
·
Jan. 18, 18 · Tutorial
Likes (5)
Comment
Save
Tweet
Share
264.2K Views

Join the DZone community and get the full member experience.

Join For Free

In this blog post, we will learn how to create custom validators in Angular Reactive Forms. If you are new to reactive forms, learn how to create your first Angular reactive form here.

Let's say we have a login form as shown in the code below. Currently, the form controls do not have any validations attached to it.

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null),
        password: new FormControl(null),
        age: new FormControl(null)
    });
}

Here, we are using FormGroupto create a reactive form. On the component template, you can attach loginForm as shown in the code below. Using property binding, the formGroup property of the HTML form element is set to loginForm and the formControlName value of these controls is set to the individual FormControl property of FormGroup.

This will give you a reactive form in your application:

Using Validators

Angular provides us many useful validators, including required, minLength, maxLength, and pattern. These validators are part of the Validators class, which comes with the @angular/forms package.

Let's assume you want to add a required validation to the email control and a maxLength validation to the password control. Here's how you do that:

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
        age: new FormControl(null)
    });
}

To work with validators, make sure to import them into the component class:

import { FormGroup, FormControl, Validators } from '@angular/forms';  

On the template, you can use validators to show or hide an error message. Essentially, you are reading formControl using the get() method and checking whether it has an error or not using the hasError() method. You are also checking whether formControl is touched or not using the touched property.

If the user does not enter an email, then the reactive form will show an error as follows:

Custom Validators

Let us say you want the age range to be from 18 to 45. Angular does not provide us range validation; therefore, we will have to write a custom validator for this.

In Angular, creating a custom validator is as simple as creating another function. The only thing you need to keep in mind is that it takes one input parameter of type AbstractControl and it returns an object of a key-value pair if the validation fails.

Let's create a custom validator called ageRangeValidator, where the user should able to enter an age only if it's in a given range.

The type of the first parameter is AbstractControl, because it is a base class of FormControl, FormArray, and FormGroup, and it allows you to read the value of the control passed to the custom validator function. The custom validator returns either of the following:

  1. If the validation fails, it returns an object, which contains a key-value pair. Key is the name of the error and the value is always Booleantrue.
  2. If the validation does not fail, it returns null.

Now, we can implement the ageRangeValidator custom validator in the below listing:

function ageRangeValidator(control: AbstractControl): { [key: string]: boolean } | null {

    if (control.value !== undefined && (isNaN(control.value) || control.value < 18 || control.value > 45)) {
        return { 'ageRange': true };
    }
    return null;
}

Here, we are hardcoding the maximum and minimum range in the validator. In the next section, we will see how to pass these parameters.

Now, you can use ageRangeValidator with the age control as shown in the code below. As you see, you need to add the name of the custom validator function in the array:

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
        age: new FormControl(null, [ageRangeValidator])
    });
}

On the template, the custom validator can be used like any other validator. We are using the ageRange validation to show or hide the error message.

If the user does not enter an age between 18 to 45, then the reactive form will show an error:

Now the age control is working with the custom validator. The only problem with ageRangeValidator is that the hardcoded age range only validates numbers between 18 and 45. To avoid a fixed range, we need to pass the maximum and minimum age to ageRangeValidator.

Passing Parameters to a Custom Validator

An Angular custom validator does not directly take extra input parameters aside from the reference of the control. To pass extra parameters, you need to add a custom validator inside a factory function. The factory function will then return a custom validator.

You heard right: in JavaScript, a function can return another function.

Essentially, to pass parameters to a custom validator you need to follow these steps:

  1. Create a factory function and pass parameters that will be passed to the custom validator to this function.
  2. The return type of the factory function should be ValidatorFn which is part of @angular/forms
  3. Return the custom validator from the factory function.

The factory function syntax will be as follows:

Now you can refactor the ageRangeValidator to accept input parameters as shown in the listing below:

function ageRangeValidator(min: number, max: number): ValidatorFn {
    return (control: AbstractControl): { [key: string]: boolean } | null => {
        if (control.value !== undefined && (isNaN(control.value) || control.value < min || control.value > max)) {
            return { 'ageRange': true };
        }
        return null;
    };
}

We are using the input parameters max and min to validate age control. Now, you can use ageRangeValidator with age control and pass the values for max and min as shown in the code below:

min = 10;
max = 20;
ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
        age: new FormControl(null, [ageRangeValidator(this.min, this.max)])
    });
}

On the template, the custom validator can be used like any other validator. We are using ageRange validation to show or hide an error message:

In this case, if the user does not enter an age between 10 and 20, the error message will be shown as seen below:

And there you have it: how to create a custom validator for Angular Reactive Forms.

AngularJS

Published at DZone with permission of Dhananjay Kumar, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Rediscovering Angular: Modern Advantages and Technical Stack
  • Angular Input/Output Signals: The New Component Communication
  • Azure Deployment Using FileZilla
  • Angular RxJS Unleashed: Supercharge Your App With Reactive Operators

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!