domingo, 19 de agosto de 2018

Mi primera aplicación web con React


Bueno, por azares del destino, finalmente fue inevitable tener que adquirir el gusto de React. Es la tendencia, culpa de Facebook. Habiéndome desahogado, empecemos.

Intro a React.js

React.js es una herramienta de JavaScript para construir interfaces de usuario. La forma más fácil de crear el esqueleto de una aplicación de React, es utilizar la herramienta de Node JS llamada create-react-app (😒), la cual podemos instalar de forma global a través de la terminal mediante el siguiente comando (nótese que debe ejecutarse como administrador -en Windows- o root -en Linux-):

# npm install -g create-react-app

Luego, procedemos a crear la aplicación base, con el nombre "peliculas-app" (pronto verán el porqué del nombre):

$ create-react-app peliculas-app

Luego, nos trasladamos al nuevo directorio creado para la app, y la probamos ejecutar:

$ cd peliculas-app/
$ npm start

Esto compila la aplicación con Webpack y la ejecuta con un servidor interno de desarrollo, publicándola localmente en el puerto 3000, por defecto. Al abrir la aplicación web, se muestra lo siguiente:

Al observar la estructura de la aplicación, tenemos algo similar a esto:
La página principal se encuentra en el archivo public/index.html. Por otra parte, el componente principal de React, el cual renderiza todo el contenido mostrado en la página inicial, se encuentra en el archivo src/App.js. En este último archivo, por ejemplo, podemos reemplazar el contenido del párrafo que usa la clase App-intro, con el texto "Hola mundo", así:

Una vez que se guarda el archivo, se recompila la aplicación de forma automática, por lo que podemos ver el cambio reflejado en el navegador de forma casi inmediata:

Creación de la aplicación: lista de películas

Luego de esta rápida introducción práctica a React, procederé a crear mi primera aplicación web con React. La aplicación consistirá en mostrar en pantalla un listado de nombres de películas, obtenidos desde un arreglo de datos. La película incluirá el título, una breve sinopsis y una imagen. El listado, así como cada ítem de este, será un componente distinto. Comencemos:

1. Primero agregaremos el listado de películas en el estado de la aplicación. Pondremos 3 para este ejemplo:


2. Luego crearemos un nuevo componente para mostrar cada ítem de la lista, en el cual mostraremos la imagen, el nombre y la sinopsis de esta. Cada ítem sera un elemento de tipo <li>. Dicho componente se creará en un nuevo archivo de JavaScript, al que llamaremos Item.js, dentro de la carpeta src.


En este componente se recibe como parámetro la variable props, la cual nos sirve para recibir datos de quien invoque este componente. En este caso, dentro de props recibiremos el campo pelicula, el cual contendrá la información de un elemento de la lista de películas: id, nombre, sinopsis y urlImagen. El componente renderiza la vista HTML que definimos en el cuerpo de la función, y en la cual podemos hacer uso de los props al incluirlos entre llaves.

3. Seguidamente procedemos a crear un tercer componente, en un nuevo archivo que nombraremos Lista.js. Este componente será el encargado de renderizar la lista, haciendo uso del componente Item para renderizar cada elemento, de la siguiente forma:


Nótese que este componente recibe el parámetro listaPeliculas dentro de los props, el cual contendrá el arreglo de películas. Este arreglo se itera mediante la función map(), dentro del cuerpo de la lista (<ul></ul>), para convertir cada elemento del arreglo en una vista, haciendo uso del componente Item. Puede observarse que el elemento es pasado a cada Item mediante el atributo pelicula, que es el nombre con el que se le hace referencia en dicho componente. Cabe mencionar que para hacer uso del componente Item, debemos importarlo al inicio del archivo de javascript.

4. Para armar la aplicación final, sustituimos en el componente principal (App.js) el párrafo que contenía la frase "Hola Mundo", por un div, y dentro de este colocamos el elemento Lista, al cual le proporcionaremos el arreglo de películas a través del atributo listaPeliculas, que es el nombre con el cual le hacemos referencia en dicho componente. Cabe recordar que para poder utilizar el componente Lista, debemos importarlo antes.


El resultado final del componente principal contenido en App.js es el siguiente:


5. Finalmente, para mostrar las películas de forma ordenada, agregamos algunos estilos CSS al final del archivo App.css, para aplicarlos globalmente a través del componente principal:


El resultado es el siguiente:
El código fuente de este ejemplo lo pueden encontrar acá: https://github.com/guillegr123/react-primera-app

Intenté que los commits fueran quedando conforme a cada paso descrito en esta entrada del blog. Pueden consultarlos acá: https://github.com/guillegr123/react-primera-app/commits/master

Conclusiones

Después de haber hecho esta primera prueba con React, resulta que se parece a Vue 2, jajaja. Al menos hasta donde pude ver, el concepto de componente es similar. Seguiré viendo qué tan parecido es a medida vaya progresando con esta herramienta.

Saludos. Happy coding!

jueves, 16 de agosto de 2018

SQL Server Snippets - Columna de fecha de última modificación en SQL Server

Supongamos que por cuestiones de control de modificaciones y auditoría, se quiere contar con un campo de fecha de última modificación en todas las tablas de una base de datos de SQL Server.

El inconveniente es que SQL Server no posee nativamente un tipo de dato que guarde la fecha de última modificación de un registro, el cual se actualice automáticamente al modificar una fila de datos. Por ello, una alternativa a esto es definir una columna de tipo datetime en cada tabla que se actualice cada vez que se modifique uno o más registros de esta, a través de un trigger.

Futuros nuevos posts... (viejo post del 2013)

¡Howdy! No pude resistirme, tengo varios posts en mente, pero no he tenido el tiempo de escribirlos, así que para mientras, quiero comentarles mis ideas, que espero alguna vez publicar:
  • Técnicas DRY para SQL Server: Son varias ideas para evitar código repetitivo en SQL Server.
  • Más SQL Server Snippets:Sé que tengo un par más por allí...
  • El regreso de las ventanas DIV: Ventanas DIV móviles, con sombra y otros efectos.
  • Symfony 2 y casos especiales de Symfony 1.4: Casi siento que he traicionado a Symfony por MVC, pero espero retomar el tema en este año, y compartir algunas cosas interesantes sobre la vieja y confiable versión 1.4.
  • Instalación de Oracle en Ubuntu: Ya tengo el PDF, y me gustaría publicarlo. Fue una tarea que hicimos en conjunto con unos amigos para la materia de Administración y Seguridad de Bases de Datos en la universidad. Ha sido el proyecto de computación más frustrante que he hecho hasta la fecha, creo que repetimos la instalación al menos unas 15 veces en dos semanas, hasta que sirvió... Menos mal que existía VirtualBox, porque si no, nos hubiera tocado formatear la computadora de pruebas 15 veces, jajaja...
  • FluentViewModel: La cereza de mi sundae, jejeje. Es un proyecto en C# que hice, que consiste en una interfaz fluida para la definición de Modelos de Vista (View Models) en MVC Framework, que hace uso de clases genéricas y expresiones lambda. Está basado en FluentValidation para .NET. Espero publicar el código fuente como Open Source algún día.
Espero publicar estos posts en un futuro cercano, ojalá lo logre...

Saludos, feliz viernes :)

Publicado originalmente el 2013-03-14, en https://itsouvenirs.wordpress.com/2013/03/14/futuros-nuevos-posts/.

Viejos posts publicados

Saludos a todos. Estuve revisando un poco mis documentos y encontré algunos posts que ya tenía listos para publicar desde hace varios años. Un par de ellos fueron colaboraciones al blog de un amigo de la universidad, y otros en realidad son manuales que escribí para acordarme cómo hacer las cosas. Les dejo abajo los enlaces a dos de estos posts, y espero posteriormente incluir otros más:
Para finalizar esta entrada, les dejo una frase un tanto soberbia de Nikola Tesla, con respecto al trabajo de Thomas Alva Edison:
"If Edison had a needle to find in a haystack, he would proceed at once with the diligence of the bee to examine straw after straw until he found the object of his search... I was a sorry witness of such doings, knowing that a little theory and calculation would have saved him ninety per cent of his labor."
- Nikola Tesla, New York Times, October 19, 1931
Traducido:
"Si Edison tuviera que encontrar una aguja en un pajar, procedería inmediatamente con la diligencia de una abeja a examinar paja por paja hasta que encontrara el objeto de su búsqueda... Fui testigo arrepentido de tales hechos, sabiendo que un poco de teoría y cálculo le hubiera ahorrado el noventa por ciento de su tarea."
- Nikola Tesla, New York Times, 19 de octubre de 1931
Es muy curioso que esta frase parece mostrarse reactiva o contrastante a la siguiente frase de Edison:
"No me equivoqué mil veces para hacer una bombilla, descubrí mil maneras de cómo no hacer una bombilla."
- Thomas Alva Edison
Esta frase la encontré en un archivo viejo en el que tenía una recopilación de frases que me habían llamado la atención. Nikola Tesla es uno de mis científicos favoritos, y según parece sus invenciones no son muy conocidas incluso en la actualidad, en comparación con el trabajo de Thomas Alva Edison.

Feliz día.

Publicado originalmente el 2013-03-04, en https://itsouvenirs.wordpress.com/2013/03/04/viejos-posts-publicados/.

PLT Scheme - Verificar que una cadena contiene solo letras minúsculas

Hola otra vez! Ahora espero no extenderme demasiado, como la primera vez. Bueno, esta es una pequeña “abstracción funcional” en PLT Scheme (ahora Racket), que verifica que una cadena este compuesta solamente por letras minúsculas.



Aunque parezca una función sencilla, contemplad que tiene algo interesante: se transforma la cadena de caracteres a una lista de caracteres (que contiene elementos tipo char), y se envía como parámetro a la función auxiliar, soloMinAux?, donde luego se extrae cada caracter, se transforma en un entero correspondiente al código ASCII en base diez, y he alli la magia, solo se verifica que este número esté entre los correspondientes a las letras minúsculas. Voilá (creo que así se escribe). Esto facilita mucho el trabajo a la hora de verificar si un carácter pertenece a una lista de caracteres consecutivos en el código ASCII. Además, las funciones string->list (que convierte una cadena a lista de caracteres) y char->integer (que convierte un caracter a un entero decimal correspondiente a su código ASCII) pueden ser de utilidad para manipular de muchas formas las cadenas de caracteres y los caracteres por si solos.

Bueno, espero que esta función les sea de utilidad, al menos para ver como se puede trabajar con caracteres y el código ASCII, y también supongo que les alegrará saber que hoy no me extendí mucho (aunque alguien dijo que ojala argumentara bastante cuando hablo, así como cuando escribo), pero bueno... Así que por el momento me despido, y les dejo esta frase, para todos aquellos que tienen una forma particular de ubicar sus cosas en el grandioso desorden que con mucho cariño llaman escritorio.
If a cluttered desk is the sign of a cluttered mind, what is the significance of a clean desk?
- Laurence J. Peter

Publicado originalmente el 2013-03-04, en https://itsouvenirs.wordpress.com/2013/03/04/plt-scheme-verificar-que-una-cadena-contiene-solo-letras-minusculas/.

jueves, 9 de agosto de 2018

Ejecutar aplicaciones con GUI desde Docker en Linux


Hace unos días un amigo me animó a descargar y correr su aplicación que había desarrollado en Python utilizando Tensorflow. Debido a que no tenía instalado Tensorflow, elegí la opción de descargar y ejecutar una imagen de contenedor de Docker ya preparada con Python y TensorFlow, en lugar de instalar todo lo necesario directamente en mi sistema operativo. Cuando llegué al punto de intentar correrlo, descubrí que tenía una interfaz de usuario gráfica (GUI), la cual no podía ser ejecutada desde la línea de comandos de mi contenedor.

Despues de investigar un poco, descubrí que es posible ejecutar aplicaciones con interfaz gráfica desde docker, siguiendo unos simples pasos que detallo a continuación, para el caso de contenedores Linux corriendo sobre host Linux:

  1. Si docker se está ejecutando con el super usuario local (root), es necesario permitir que este se pueda conectar al servidor X encargado de administrar el ambiente gráfico, agregándolo a la lista de usuarios permitidos, mediante el siguiente comando:

    # xhost local:root

  2. Ejecutar un nuevo contenedor, de la siguiente forma:

    $ docker run -ti --net host \
        -v /tmp/.X11-unix:/tmp/.X11-unix \
        -e DISPLAY=unix$DISPLAY \
        ubuntu:latest bash

    Notar las siguientes partes del comando:
    1. Se esta creando y ejecutando un nuevo contenedor con la última imagen estable de Ubuntu (ubuntu:latest), como ejemplo.
    2. Una vez se inicie el contenedor, se ejecutará la línea de comandos de este (bash).
    3. Las opciones -ti indican que se desea asignar una pseudo-terminal al contenedor, y mantener habilitada la entrada estándar mientras el contenedor se esté ejecutando, respectivamente.
    4. Ejecutamos el contenedor utilizando el driver del host para el uso de la red, mediante la opción --net host
    5. Montamos el socket de X11 como un volumen compartido con el contenedor, mediante la opción -v /tmp/.X11-unix:/tmp/.X11-unix
    6. Compartimos la variable de entorno DISPLAY del host, con el contenedor, mediante -e display="unix$DISPLAY
  3. Una vez la línea de comandos del nuevo contenedor se está ejecutando, para probar que podemos iniciar y ver aplicaciones on interfaz gráfica, instalaremos NEdit, que es un editor liviano para X Windows System. Para ello procedemos a actualizar la lista de paquetes de los repositorios de Ubuntu, e instalar el editor:

    # apt-get update & apt-get install nedit

  4. Finalmente ejecutamos el editor desde la línea de comandos:

    # nedit

    Veremos como la interfaz gráfica de la aplicación es lanzada en el sistema operativo host, ya que esta siendo ejecutada en el servidor X de este:


Referencias

Con la tecnología de Blogger.