Archivo de la categoría: js

TypeScript nos da la tranquilidad en el frontend

Cuando empecé a programar para web me encontraba cómodo con PHP y Javascript, me permitían el salvaje mundo de no definir la estructura de los datos y de reutilizar variables. Mientras, estaba aprendiendo Java y «sufriendo» la definición de clases y tipos. Era joven e inexperto. No sabía que esto está muy bien cuando estás tirando código rápido tú solo. Está bien para prototipar, hacer una prueba de concepto con pocos ficheros y pocas funciones, cuando tienes todo el código en tu cabeza. Ideal para un hackaton o similar.

Pero cuando llegas al mundo real, empiezas a utilizar librerías, a compartir código con otras personas, a tener que entender como funciona código ajeno (a veces sin leer documentación, por que no la hay). Si, ahora prefiero un código que se expresa por si solo, más allá de buenos nombres de variables o funciones, está un buen tipado, entender que puedo esperar de una función y como espera esa función ser usada, construir objetos que tienen sentido.

TypeScript evoluciona JavaScript, de hecho es más «java» ya que no solo tiene orientación a objetos sino que me devuelve a ese fuerte tipado. Sin embargo, los navegadores ejecutan javascript, así que el código TypeScript que hagamos tendrá que llevar una fase de compilación para convertirse en JS. Lo bueno, que en esa compilación saltarán errores de tipado que nos ayudarán a tener un JS más limpio y estable, pillando errores como asignaciones inválidas antes de runtime, lo que reduce bugs en producción hasta un 15-20%.

La curva de aprendizaje es mayor que JS, y quizá podemos entrar haciendo JS (para conocer como funciona y sabiendo que podríamos estar haciendo chapuzas) y luego dar el salto a TS para aprender de interfaces y tipos. Las interfaces definen contratos para objetos/APIs, facilitando el uso de funciones ajenas como cajas negras (sabemos lo que tenemos que darle y tenemos garantizado lo que sale, nos da igual lo que pasa dentro).

La principal desventaja es que hay que preparar un entorno de compilación y eso puede resultar engorroso poner en marcha. Además esa compilación lleva a retrasar unos segundos cada cambio que hagamos en nuestro desarrollo para poder probarlo. Pero si vamos a trabajar con frameworks modernos, con proyectos medianos-grande… no lo dudaría ni un segundo.

Por otro lado, que placer es el autocompletado que te aporta en el IDE poder tener clara la librería que estás usando.

Proyectos legacy: de JS a TS

[Leer más en TypeScript: Migrating from JavaScript]

Lo ideal en un proyecto legacy es ir cambiando piezas poco a poco, no queremos tirarlo todo y empezar de cero. La compilación de TypeScript permite usar código JS puro, pero aquí entraremos en terreno pantanoso que tendremos que andar con cuidado.

Lo ideal en este caso será reemplazar de fuera hacia dentro, ya que el core suele estar fuertemente acoplado. Iremos migrando piezas por su valor en negocio (criticidad, mantenimiento…) a fondo e ir cambiando su nivel de «strictness» de manera local. Creamos types para lo que necesiten estos módulos (que ya se usarán en toda la aplicación) y separamos responsabilidades.

Lamentablemente (o como solución temporal), usaremos el type any con toda relación con el núcleo que no ha sido migrado (dejando anotada esta deuda), pero solo en esas conexiones.

Cuando estén migrados todas las capas exteriores podremos ponernos serios con el core de la aplicación y levantar el nivel de strict de manera global.

La mejor manera de esperar a que el DOM esté listo y poder manipularlo

Aún recuerdo mis tiempos de jQuery (si, esa librería ha sido una gran herramienta durante mucho tiempo) en que había que esperar a $(document).ready() para garantizar que el DOM y las librerías habían cargado para poder ejecutar código y que todo funcionara.

Pero cuando empezamos a poner el javascript al final del HTML (si, fuera del Header) para aliviar los tiempos de carga provocamos que en realidad no hiciera falta esperar, porque si se había cargado ese código es porque ya se había parseado todo el DOM.

Pero ¿eso quiere decir que el DOM está listo? ¿que se han cargado todos los elementos? Pues se han cargado todos los elementos renderizados en servidor, PERO actualmente hay mucho renderizado que se hace en cliente (React, Angular… )

Así que si queremos manipular el DOM, necesitamos garantizar que existe ese elemento que queremos manipular. Puede que se lance un script cuando el DOM está listo pero necesite esperar a que ese elemento esté disponible.

La solución habitual es hacer un bucle con setTimeout que hace una comprobación cada cierto tiempo y se lanza a si mismo si no encuentra el elemento para intentarlo de nuevo.

function check() {
  if (!$('#elementId').size()){
    setTimeout(check, 200);
  } else {
    // el código a ejecutar
  }
}

Y esto puede que funcione, pero no es la manera más eficiente… y con los navegadores modernos puede que falle porque, cuando la pestaña / ventana no esté en primer plano puede que ahorren recursos y no corran ese código suficientemente «rápido».

Así que toca hacer una solución moderna para navegadores modernos, que no dependa de que la pestaña esté funcionando, o de que el timeout se ejecuta a tiempo. Y la respuesta es requestAnimationFrame

Se suele usar para animaciones, garantizando 60 refrescos por segundo. Pero también se puede usar para notificar al código que está esperando.

Así que usaremos algo como:

function check() {
  if (!$('#elementId').size()){
    window.requestAnimationFrame(check);
  } else {
    // el código a ejecutar
  }
}

Y aunque en teoría podría parecer que este código se comprobaría el DOM cada 1/60 de segundo para comprobar el elemento buscado, solo se hará una vez, cuando el elemento sea renderizado.

Y así es la manera adecuada de esperar a un elemento de DOM en los navegadores modernos.

Mas info: Swizec

Chrome dev tools: Como explorar un JSON

Si te dedicas al mundo del frontend, seguramente tienes que estar consultando un API REST que te devuelve documentos en formato JSON y en ocasiones querrás comprobar que lo que recibes es lo que esperar y poder explorarlo. Vamos a a ver un par de trucos para atacar rápidamente un JSON gigante usando las Developer Tools del navegador Google Chrome (o Chromium) y facilitarte la vida.

Truco 1: Cargar en el terminal

La consola de las Developer Tools no es solo l lugar donde probar el código, también podemos hacernos.

Con las DevTools abiertas, en la pestaña Network, realizamos la petición al API REST. Entonces abriremos el documento que hemos recibido y nos iremos a la pestaña preview y veremos el JSON en todo su esplendor. Entonces, seleccionando el elemento raíz, abrimos el menú contextual (botón derecho) y elegimos «Store to global variable».

Desde ese momento tendremos una variable (en mi caso fue temp1) con la que podremos trabajar en el terminal. Podremos hacer operaciones de array o de objeto sobre sus elementos y usar el autocompletado para hacer todo el path. Si escribimos el path y damos intro recibiremos el valor de ese elemento en el árbol JSON.

Truco 2: Extraer el path a un elemento

Un caso bastante habitual es tener un elemento bastante profundo en el árbol JSON y no querer tener problemas de erratas al transcribirlo. Puedes sacar el menú contextual del elemento y

Y puedes comprobar que está correctamente escibiendo en la consola:

temp1.PATH_COPIADO

Bola Extra: Una extensión para ver JSON.

Si no quieres tener que hacer el recorrido hasta las dev tools, y quieres ver directamente el JSON al llamar a su url en el navegador de una manera manejable, te recomiendo instalar JSON Formatter.

Truco: puedes expandir y contraer ramas pulsando ctrl para que lo haga con todas las del mismo nivel.