Aprende a implementar y personalizar validaciones asíncronas en Angular con este tutorial práctico. Mejora la validación de formularios en tus aplicaciones Angular de manera sencilla y efectiva.
November 19, 2024 , 4 min read
Share with:En el mundo del desarrollo web con Angular, las validaciones asíncronas desempeñan un papel crucial en la garantía de datos confiables y actualizados en nuestros formularios. Imagina verificar la disponibilidad de un nombre de usuario en tiempo real o validar la autenticidad de un correo electrónico mientras el usuario completa un formulario. Estas son solo algunas de las situaciones en las que las validaciones asíncronas entran en juego. En este tutorial, te sumergirás en el emocionante mundo de las validaciones asíncronas personalizadas en Angular, aprendiendo a implementar soluciones innovadoras y a la medida que harán que tus aplicaciones sean más eficientes y atractivas. ¡Prepárate para dar vida a tus formularios con validaciones dinámicas y poderosas!
"Normalmente, estas solicitudes se realizan a un backend real. Sin embargo, para este ejemplo, utilizaremos la API pública https://fakestoreapi.com/users
como fuente de datos de prueba. Simulará la respuesta que un backend devolvería, permitiéndonos realizar nuestras validaciones asíncronas dentro del proyecto Angular."
user.json
[
{
id:1,
email:'John@gmail.com',
username:'johnd',
password:'m38rmF$',
name:{
firstname:'John',
lastname:'Doe'
},
address:{
city:'kilcoole',
street:'7835 new road',
number:3,
zipcode:'12926-3874',
geolocation:{
lat:'-37.3159',
long:'81.1496'
}
},
phone:'1-570-236-7033'
},
/*...*/
{
id:20,
email:'...',
username:'...',
password:'...',
name:{
firstname:'...',
lastname:'...'
},
address:{
city:'...',
street:'...',
number:...,
zipcode:'...',
geolocation:{
lat:'...',
long:'...'
}
},
phone:'...'
}
]
Este es un servicio en Angular que utiliza el módulo HttpClient
para realizar solicitudes HTTP a una API externa (https://fakestoreapi.com/users
). El método userEmailAsync()
devuelve un observable que representa la respuesta de la solicitud HTTP, lo que permite que los componentes de Angular suscriban y reciban los datos del usuario de manera asíncrona. Este servicio se puede inyectar en otros componentes de Angular para obtener los datos del usuario y utilizarlos en la aplicación.
app.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { ProductInterface } from '../interfaces/product.interface';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ProductService {
constructor(
private readonly _http: HttpClient
) { }
userEmailAsync(): Observable<any> {
return this._http.get<any>('https://fakestoreapi.com/users');
}
}
En este componente se inicializa nuestro reactive froms y nuestra validacion asincrona validarEmail Se observa como en nuestro FormBuilder.group. Como ven primero va el valor por defecto, luego declaramos el conjunto de la validaciones sincronas y luego el conjunto de validaciones asíncronas.
app.component.ts
import { Component, OnInit } from "@angular/core";
import {
FormBuilder,
FormGroup,
Validators,
AbstractControl
} from "@angular/forms";
import { AppService } from "./app.service";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
myForm: FormGroup;
constructor(private fb: FormBuilder, private productService: ProductService) {}
ngOnInit() {
this.myForm = this.fb.group({
name: ["", Validators.required],
email: [
"",
[Validators.required, Validators.email],
this.validarEmail.bind(this)
]
});
}
validarEmail(control: AbstractControl) {
const email = control.value.toLowerCase();
return this.productService.userEmailAsync().pipe(
map(users => {
return users.some((user: any) => user.email.toLowerCase() === email) ? null : { invalidEmail: true };
})
);
}
}
Nuestro validador es muy similar a un validador personalizado típico. Aquí hemos definido nuestro validador en la clase de componente directamente en lugar de un archivo separado. Esto facilita el acceso a nuestra instancia de servicio inyectado. Observe también cómo necesitamos vincular this valor para asegurarnos de que apunta a la clase de componente.
app.component.html
<div style="text-align:center">
<form [formGroup]="myForm">
<input type="text" formControlName="name">
<input type="email" formControlName="email">
<div *ngIf="myForm.get('email').status === 'PENDING'">
Checking...
</div>
<div *ngIf="myForm.get('email').status === 'VALID'">
Email valido
</div>
<div *ngIf="myForm.get('email').errors ">
Este email no es correcto
</div>
</form>
</div>