Angular Async validators
Angular Async validators are a powerful tool that can help you validate user input in real-time. They allow you to perform asynchronous validation checks on user input, such as checking if a username is already taken or if an email address is valid. To use Angular Async validators, you need to create a custom validator function that returns a Promise or an Observable. This function will be called every time the user types something in the input field. If the Promise or Observable resolves with a value, the input is considered valid. If it rejects with an error message, the input is considered invalid. Here's an example of how to create an Async validator in Angular:
import { AbstractControl, ValidationErrors } from '@angular/forms';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export function uniqueUsernameValidator(control: AbstractControl): Promise | Observable {
const username = control.value;
return checkUsernameAvailability(username).pipe(
map(isAvailable => isAvailable ? null : { uniqueUsername: true })
);
}
function checkUsernameAvailability(username: string): Observable {
// Make an HTTP request to check if the username is available
return http.get(`/api/check-username-availability?username=${username}`);
}
In this example, `uniqueUsernameValidator` is a function that takes an `AbstractControl` as input and returns a Promise or an Observable of `ValidationErrors` or `null`. It calls the `checkUsernameAvailability` function, which makes an HTTP request to check if the username is available. If the username is available, the Promise or Observable resolves with `null`, indicating that the input is valid. If the username is not available, the Promise or Observable resolves with an object containing the `uniqueUsername` property, indicating that the input is invalid. To use this validator in a form, you need to add it to the `validators` array of the form control:
import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { uniqueUsernameValidator } from './validators';
@Component({
selector: 'app-signup-form',
template: `
`,
})
export class SignupFormComponent {
form = new FormGroup({
username: new FormControl('', [Validators.required], [uniqueUsernameValidator]),
});
}
In this example, the `uniqueUsernameValidator` is added to the `username` form control as an Async validator. The error messages are displayed using Angular's built-in `ngIf` directive. Async validators can also be used in template-driven forms:
In this example, the `uniqueUsernameValidator` is added to the `username` input field using the `asyncValidators` directive.
In conclusion, Angular Async validators are a powerful tool that can help you validate user input in real-time. They allow you to perform asynchronous validation checks on user input, such as checking if a username is already taken or if an email address is valid. To use Async validators, you need to create a custom validator function that returns a Promise or an Observable. This function will be called every time the user types something in the input field. If the Promise or Observable resolves with a value, the input is considered valid. If it rejects with an error message, the input is considered invalid.
Asynchronous validators allows you to validate form information against your backend (using $http).
These kind of validators are needed when you need to access server stored information you can't have on your client for various reasons, such as the users table and other database information.
To use async validators, you access the ng-model of your input and define callback functions for the $asyncValidators property.
Example:
The following example checks if a provided name already exists, the backend will return a status that will reject the promise if the name already exists or if it wasn't provided. If the name doesn't exist it will return a resolved promise.
ngModel.$asyncValidators.usernameValidate = function (name) {
if (name) {
return AuthenticationService.checkIfNameExists(name); // returns a promise
} else {
return $q.reject("This username is already taken!"); // rejected promise
}
};
Now every time the ng-model of the input is changed, this function will run and return a promise with the result