¿Cómo realizar validaciones asincrónicas en un formulario?
Las validaciones asincrónicas son clave para ofrecer una experiencia de usuario fluida y optimizada. Imagina estar llenando un formulario largo, llegar al final para guardar la información y ¡sorpresa! aparece un error. Esto puede ser frustrante, ¿verdad? Mediante el uso de validaciones asincrónicas, podemos alertar al usuario de inmediato si el nombre ya está en uso, similar a cuando creas un correo en plataformas como Hotmail. Exploraremos el uso de una API que verifica la disponibilidad de categorías en tiempo real a medida que el usuario ingresa la información.
¿Cómo funciona el endpoint de disponibilidad?
Para realizar la validación asincrónica, utilizaremos un endpoint específico de nuestra API que verifica la disponibilidad de una categoría.
Ruta completa:API categories availability
Método: POST
Funcionalidad: Envía el nombre de la categoría deseada por crear y devuelve un JSON con un valor booleano indicando si está disponible (true) o no (false).
Este es el primer paso para conectar nuestra validación asincrónica con el frontend.
¿Cómo implementar la validación en el servicio?
Primero, debemos implementar un método en nuestro servicio categories service que se conecta al endpoint de disponibilidad. Aquí te mostramos cómo hacerlo:
functioncheckCategory(name){returnthis.http.post('categories/availability',{ name });}
Este método envía el nombre de la categoría al endpoint y espera la respuesta de disponibilidad. Podemos especificar en el código que esperamos un booleano como respuesta.
¿Cómo crear la validación en validators?
Dentro de nuestra clase de validaciones personalizadas (validators), redactamos la lógica de la validación asincrónica. Aquí se utiliza el poder de crear funciones dentro de funciones, una práctica común en lenguajes como JavaScript.
import{ map }from'rxjs/operators';staticvalidateCategory(service){return(control)=>{const value = control.value;return service.checkCategory(value).pipe(map(response=> response.isAvailable?null:{notAvailable:true}));}}
Este fragmento de código toma el valor del control, verifica su disponibilidad usando el servicio y retorna null si está disponible o un error si no lo está. Es esencial que comprendas el funcionamiento de observables y operators de RxJS para transformar las respuestas adecuadamente.
¿Cómo aplicar la validación al formulario?
Una vez configurada nuestra validación, es momento de integrarla con el formulario de categorías:
Incluimos nuestras validaciones sincronas primero (Validators.required y Validators.minLength), seguidas de nuestra validación asincrónica personalizada.
¿Cómo se visualizan los errores en el formulario?
Para mejorar la experiencia del usuario, mostramos mensajes de error junto al campo correspondiente si hay algún problema con la validación.
<div*ngIf="form.errors?.notAvailable"> Este nombre ya lo tiene otra categoría.
</div>
Estos mensajes proporcionan un feedback claro e inmediato al usuario, ayudándoles a corregir errores antes de seguir completando el formulario.
Esperamos que este enfoque para implementar validaciones asincrónicas te sea útil para mejorar tus desarrollos. A medida que vayas adquiriendo práctica, estas técnicas se volverán parte de tu arsenal de herramientas para desarrollar interfaces dinámicas y responsivas. ¡Sigue aprendiendo y éxitos en tus proyectos!
Validaciones Asíncronas con API para Formularios de Categorías
Por cierto, quiero aclarar, que no es la forma correcta para afrontar este tipo de validación asíncrona por que no es muy correcto o más bien nada correcto mandar toda la información del back para validar si existe o no un nombre de un elemento, sin embargo para poder entender la validación asíncrona de los formularios es una forma de parchar que no existe el end point que debería validarlo.
La validación asíncrona es como tener un guardia de seguridad en la puerta de un evento en lugar de esperar a que la persona llegue a la barra para pedirle su identificación. Al consultar directamente con la base de datos (a través de una API) mientras el usuario escribe, evitas que llene todo un formulario largo solo para recibir un frustrante error al final al hacer clic en "Guardar".
En términos prácticos, esto mejora drásticamente la experiencia del usuario (UX). Imagina el proceso de crear un nuevo correo electrónico: el sistema te avisa de inmediato si el nombre de usuario ya está tomado. En Angular, logramos esto conectando el FormControl a un servicio que hace una petición HTTP. Si el nombre ya existe, la API responde y nosotros bloqueamos el input al instante, mostrando un mensaje claro. Es la forma más proactiva de asegurar la integridad de los datos antes de que se envíen al servidor.
Pero aun así puedes realizar el ejercicio de la siguiente manera:
CategoryService:
// Agreguen el import de map de rxjs/operatorsimport{ map }from'rxjs/operators';checkAvailability(name:Category['name']){returnthis.getAll().pipe(map((categories)=>{const isAvailable =!categories.some((category)=> category.name=== name);return isAvailable;}));}```Validators:
```js
// Agreguen el import de map de rxjs/operatorsimport{ map }from'rxjs/operators';staticvalidateCategory(service:CategoriesService){return(control:AbstractControl)=>{const value = control.value;return service.checkAvailability(value).pipe(map((response)=>{const isAvailable = response;if(!isAvailable)return{not_available:true};returnnull;}));};}
Con esto, ya lo demás debería funcionar sin problemas.
*Nota: Esto <u>NO</u> es una buena práctica, ya que estamos llamando a nuestro endpoint '/categories' cada vez que cambiamos en el input para validar si existe. Lo mejor es que nuestro backend realice esta operación en la base de datos de forma más eficiente. Esto es solo con fines de realizar el ejercicio para los que quieran ver cómo funciona las validaciones asincrónicas en Angular.
Espero le sirva a alguien :)
Si vienes del futuro como yo donde no existe el endpoint donde deben hacerse las peticiones para validar si el nombre existe o no, hagan la petición a el método getAllCategories del archivo de servicios, y el método de los validators debería quedar de la siguiente manera: