Introducción
En este artículo, aprenderemos sobre validaciones en formas reactivas en Angular. Crearemos un formulario de registro de usuario simple e implementaremos algunas validaciones incorporadas en él. Junto con las validaciones incorporadas, también implementaremos algunas validaciones personalizadas para el formulario reactivo.
Consideraremos las siguientes validaciones personalizadas para esta demostración:
- Verifique la disponibilidad del nombre de usuario
- Validación del patrón de contraseña
- Coincide con la contraseña ingresada en dos campos diferentes
Eche un vistazo a la aplicación en acción.

Prerrequisitos
- Instale el código de Visual Studio desde aquí
- Instale la última versión de Angular CLI desde aquí
Código fuente
Obtén el código fuente de GitHub.
Crea la aplicación Angular
Navegue a la carpeta donde desea crear su archivo de proyecto. Abra una ventana de comando y ejecute el comando que se muestra a continuación:
ng new angular-forms-validation --routing=false --style=scss
Estamos especificando el comando para crear una nueva aplicación Angular. La opción para crear el módulo de enrutamiento se establece en false y la extensión de los archivos de estilo se establece en scss
. Este comando creará el proyecto Angular con el nombre angular-forms-validation
.
Cambie los directorios al nuevo proyecto y abra el proyecto en VS Code usando el conjunto de comandos que se muestra a continuación:
cd angular-forms-validation code .
Instalar Bootstrap
Ejecute el siguiente comando para instalar la biblioteca Bootstrap:
npm install bootstrap --save
Agregue la siguiente definición de importación en el styles.scss
archivo:
@import "~bootstrap/dist/css/bootstrap.css";
Crea el servicio de validación
Ejecute el siguiente comando para crear un nuevo servicio:
ng g s services\customvalidation
Este comando creará una carpeta llamada servicios que contiene dos archivos, customvalidation.service.ts
y customvalidation.service.spec.ts
. Abra el customvalidation.service.ts
archivo y coloque el siguiente código en él:
import { Injectable } from '@angular/core'; import { ValidatorFn, AbstractControl } from '@angular/forms'; import { FormGroup } from '@angular/forms'; @Injectable({ providedIn: 'root' }) export class CustomvalidationService { patternValidator(): ValidatorFn { return (control: AbstractControl): { [key: string]: any } => { if (!control.value) { return null; } const regex = new RegExp('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9]).{8,}$'); const valid = regex.test(control.value); return valid ? null : { invalidPassword: true }; }; } MatchPassword(password: string, confirmPassword: string) { return (formGroup: FormGroup) => { const passwordControl = formGroup.controls[password]; const confirmPasswordControl = formGroup.controls[confirmPassword]; if (!passwordControl || !confirmPasswordControl) { return null; } if (confirmPasswordControl.errors && !confirmPasswordControl.errors.passwordMismatch) { return null; } if (passwordControl.value !== confirmPasswordControl.value) { confirmPasswordControl.setErrors({ passwordMismatch: true }); } else { confirmPasswordControl.setErrors(null); } } } userNameValidator(userControl: AbstractControl) { return new Promise(resolve => { setTimeout(() => { if (this.validateUserName(userControl.value)) { resolve({ userNameNotAvailable: true }); } else { resolve(null); } }, 1000); }); } validateUserName(userName: string) { const UserList = ['ankit', 'admin', 'user', 'superuser']; return (UserList.indexOf(userName) > -1); } }
El método patternValidator
se utiliza para validar el patrón de contraseña en nuestro formulario. El parámetro de este método es de tipo, AbstractControl
que es una clase base para FormControl
.
Usaremos una expresión regular para validar la contraseña. Validaremos las siguientes cuatro condiciones usando la expresión regular:
- La contraseña debe tener un mínimo de ocho caracteres.
- Tiene al menos una letra minúscula.
- Tiene al menos una letra mayúscula.
- Tiene al menos un número.
Si la contraseña falla en la verificación de expresiones regulares, estableceremos la invalidPassword
propiedad en verdadero.
El método MatchPassword
se utiliza para comparar las contraseñas en dos campos. Este método aceptará dos parámetros de tipo cadena. Estos parámetros representan el nombre de los campos que se van a comparar. Obtendremos el FormControl
para estos dos campos y luego coincidiremos con los valores en ellos. Si los valores no coinciden, estableceremos la passwordMismatch
propiedad en verdadero.
El método userNameValidator
se utiliza para verificar si el nombre de usuario ya está en uso o no. Este método aceptará un parámetro de tipo AbstractControl
. Comprobaremos si está presente en una matriz estática el valor de este campo, UserList
. Si el valor ingresado por el usuario ya está presente, estableceremos la userNameNotAvailable
propiedad en verdadero.
Estamos usando la setTimeout
función para invocar esta verificación cada dos segundos. Esto garantizará que el error se produzca después de dos segundos desde que el usuario deja de escribir en el campo.
Crear el componente de forma reactiva
Ejecute el siguiente comando para crear el componente de forma reactiva:
ng g c reactive-form
Abra reactive-form.component.ts
y ponga el siguiente código en él:
import { Component, OnInit } from '@angular/core'; import { Validators, FormGroup, FormBuilder } from '@angular/forms'; import { CustomvalidationService } from '../services/customvalidation.service'; @Component({ selector: 'app-reactive-form', templateUrl: './reactive-form.component.html', styleUrls: ['./reactive-form.component.scss'] }) export class ReactiveFormComponent implements OnInit { registerForm: FormGroup; submitted = false; constructor( private fb: FormBuilder, private customValidator: CustomvalidationService ) { } ngOnInit() { this.registerForm = this.fb.group({ name: ['', Validators.required], email: ['', [Validators.required, Validators.email]], username: ['', [Validators.required], this.customValidator.userNameValidator.bind(this.customValidator)], password: ['', Validators.compose([Validators.required, this.customValidator.patternValidator()])], confirmPassword: ['', [Validators.required]], }, { validator: this.customValidator.MatchPassword('password', 'confirmPassword'), } ); } get registerFormControl() { return this.registerForm.controls; } onSubmit() { this.submitted = true; if (this.registerForm.valid) { alert('Form Submitted succesfully!!!\n Check the values in browser console.'); console.table(this.registerForm.value); } } }
Crearemos una variable registerForm
de tipo FormGroup
. En el ngOnInit
método, estableceremos los controles para el formulario usando la FormBuilder
clase. Todos los campos se establecen como campos obligatorios para este formulario. Invocaremos el userNameValidator
método del servicio usando la función bind.
Para el campo de contraseña, usaremos el método de composición para fusionar múltiples validadores en una sola función. También invocaremos el MatchPassword
método y pasaremos el nombre de los controles de formulario password
y confirmPassword
como parámetros.
La registerFormControl
propiedad devolverá los controles de formulario del formulario. El onSubmit
método imprimirá el contenido del formulario en la consola si el formulario es válido y se envió correctamente.
Abra reactive-form.component.html
y ponga el siguiente código en él:
Angular Reactive Form
Name Name is required Email Email is required Enter a valid email address User Name User Name is required User Name is not available Password Password is required Password should have minimum 8 characters, at least 1 uppercase letter, 1 lowercase letter and 1 number Confirm Password Confirm Password is required Passwords doesnot match Register
We will create a reactive form and use the Bootstrap card for styling. The card header will contain a title whereas the card body will have the form fields. We will bind the formGroup
property of the tag to the name of our form which is
registerForm
. The onSubmit
method will be invoked on submitting the form. We will also bind the formControlName
property of each input field to the control name of our FormGroup
. We will check for errors in the form controls and then display the appropriate validation error message on the screen.
Create the nav-bar component
Run the following command to create the nav-bar component:
ng g c nav-bar
Open nav-bar.component.html
and put the following code in it:
Form Validation Demo - Reactive Form
We are adding the navigation link to the reactive form component in the nav bar.
Update the app component
Open the app.component.html
file and put the following code in it:
Update the App module
Add the following code in the app.module.ts
file. We will import the forms module and define the routing for our application. You can refer to GitHub for the complete source code of this file.
import { RouterModule } from '@angular/router'; import { ReactiveFormsModule } from '@angular/forms'; @NgModule({ ... imports: [ ... ReactiveFormsModule, RouterModule.forRoot([ { path: '', component: ReactiveFormComponent }, { path: 'reactive-form', component: ReactiveFormComponent } ]), ], })
Execution demo
We will use the following command to start the web server:
ng serve -o
This command will launch the application in your default browser at //localhost:4200/
. You can perform all the form validations which we have discussed here.
This application is also hosted at //ng-forms-validation.herokuapp.com/. Navigate to the link and play around with it for a better understanding.
Summary
We have created a sample user registration form using the reactive form approach in Angular. We have implemented the inbuilt validations as well as custom validations to the form. The Bootstrap library is used to style the form.
Get the source code from GitHub and play around with it for a better understanding.
See Also
- Localization In Angular Using i18n Tools
- Template-Driven Form Validation In Angular
- Understanding Angular Animation
- Policy-Based Authorization In Angular Using JWT
- Facebook Authentication And Authorization In Server-Side Blazor App
You can find other posts like Reactive Form Validation in Angular on Ankit Sharma's Blog.