Angular Form Control: valid vs invalid

Profundiza en los estados de los controles de los formularios en Angular

Alejandro Lora
DotTech
3 min readFeb 7, 2022

--

Photo by Leon Dewiwje on Unsplash

En este post, vamos a ver la diferencia entre valid e invalid cuando tratamos con controles de formularios (Form Control) y por qué cuando hacemos validaciones asíncronas, podemos estar usándolos mal.

Estados de los controles

Una de las propiedades interesantes de un Control es el estado (status), que nos permite saber el estado de validación del mismo. Pueden ser:

Imagen documentación oficial — link

El estado PENDING sólo aparece cuando tenemos validaciones asíncronas, y ahí es donde debemos saber bien la diferencia entre valid e invalid.

Aparte de este type, en el API del Form Control tenemos propiedades que retornan boolean: valid, invalid y pending.

Confusión usando valid/invalid

Una práctica muy común es querer mostrar un texto o desactivar un botón basado en el estado de nuestro control, es decir, usando estas propiedades. Por ejemplo, “Desactiva el botón de acción si existen errores de validación.” El código que implementaría esta expresión es el siguiente:

Lo que literalmente dice, desactiva el botón si el control es inválido. Pues bien, en validaciones asíncronas eso no funciona como esperamos.

Escenario real

Puedes abrir el enlace (https://angular-valid-invalid-reactive-forms.stackblitz.io/) para ver el ejemplo en stackblitz.

El primer input, es de validación síncrona, puedes omitirlo ahora mismo, puesto que lo hemos incluido para poder realizar la comparación. El segundo input, tiene una validación asíncrona la cual dispara un error si el nombre que introducimos es “Alejandro”, para cualquier otro nombre, no dispara ningún error.

Además, existen dos botones, los cuales usan [disabled], uno usando valid y otro invalid. Se puede observar que uno funciona tal y como se espera pero el otro tiene un comportamiento no deseado.

Observe la siguiente imagen, la validación se encuentra en el estado PENDING, y por tanto, sabemos que fallará. No obstante, el botón de más abajo no se encuentra deshabilitado porque está haciendo uso de la propiedad invalid, mientras que el primero usa la propiedad valid, el cual síque está desactivado mientras se realiza la evaluación.

El primer botón se desactiva mientras se evalúa la validación (👍) no permitiendo clicks en él. Mientras que el segundo botón permanece clickeable mientras se evalúa la validación.

Razonamiento

Esto ocurre porque el estado INVALID sólo se produce cuando la validación ha terminado, y es inválida, errónea. Mientras que el estado VALID sólo se produce cuando la validación ha terminado y es válida, sin errores.

Cuando se está evaluando la validación, podemos decir que no es ni válido, ni es inválido, por lo que la negación [disabled]="myControl.invalid" no es cierta, porque para ser inválida, debe de haber terminado la validación, y no encontrarse en el estado PENDING.

Esto puede romper la experiencia de usuario si la llamada al servidor toma más tiempo de la cuenta y el usuario hace click para enviar el formulario y no se lo impedimos.

Por esta razón, para este tipo de casos, siempre es mejor usar la negación de valid quedando de la siguiente forma [dissabled]=”!myControl.valid". Aunque sepamos que una negación siempre es menos legible que una afirmación (tips de clean code), aquí hay un buen razonamiento de por qué usarlo así.

Feedback is welcome!

Se aprecia mucho obtener feedback, saber si este post gustó mucho o poco y también puedes escribirme comentarios y sugerencias para futuros posts.

Demo y Código: Link
Twitter: https://twitter.com/alejandrocoding
Otros posts: https://medium.com/@alejandrocoding

--

--

Alejandro Lora
DotTech

Angular developer and Typescript enthusiast, passionate with Firebase and web technologies.