Validaciones asíncronas customizadas en Angular

Implementa validaciones asíncronas en angular de manera simple con este sencillo tutorial.

December 24, 2020 , 3 min read

Share with:

angular

Indice

  1. Introduccion
  2. Implementacón

Introduccion

Crear validaciones asincronas customisadas para los formularios reactivos en angular.

Las validaciones asíncronas son aquellas en las cuales debemos hacer una solicitud externa y de acuerdo a ello validar los datos, por ejemplo para validar un nombre de usuario (usersname), primero debemos hacer una solicitud a nuestra base de datos y comprobar que el nombre de usuario está disponible, esto es una validación asíncrona.

Implementación

Normalmente se realizar la solicitud a un backend real pero para este ejemplo dentro del proyeto de angular en el path /assets/user.json. Se colocara los datos de prueba a ser validadados como si fuera la respuesta que devolveria un backend.

user.json

[ { "name": "Paul", "email": "paul@example.com" }, { "name": "Ringo", "email": "ringo@example.com" }, { "name": "John", "email": "john@example.com" }, { "name": "George", "email": "george@example.com" } ]

servicio

Se creara un servicio con el método checkEmail que active una llamda GET http a nuestro archivo JSON. Se utlizara el operador delay de la librerai RxJS's para simular la latencia entre la comunicación de backend y frontend.

app.service.ts

import { Injectable } from "@angular/core"; import { Http } from "@angular/http"; import { map, delay, mergeMap, filter } from "rxjs/operators"; import { Observable } from "rxjs"; @Injectable() export class AppService { constructor(private http: Http) {} checkEmail(email: string) { console.log( "valor", this.http.get("assets/users.json").pipe( map(res => res.json()), map(users => users.filter(user => user.email === email)) ) ); return this.http.get("assets/users.json").pipe( map(res => res.json()), map(users => users.filter(user => user.email === email)) ); } }

Observe cómo filtramos para los usuarios que tienen el mismo correo electrónico que el proporcionado al método. Luego, mapeamos los resultados nuevamente y probamos para asegurarnos de que obtenemos un objeto vacío.

Validador asincrono-componente

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 signupService: AppService) {} ngOnInit() { this.myForm = this.fb.group({ name: ["", Validators.required], email: [ "", [Validators.required, Validators.email], this.validarEmail.bind(this) ] }); } validarEmail(control: AbstractControl) { return this.signupService.checkEmail(control.value).subscribe(res => { return res ? null : { emailTaken: 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.

Template HTML

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>

Redes Sociales

Sígueme en Twitter @crisjc8

Sígueme en LinkedIn Cristhian Jumbo

Sígueme en Instagram crisweb.me