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

domingo, 15 de julio de 2018

Conexión a fuente de datos (PostgreSQL) en iReport 3.7.3


Para crear reportes utilizando el asistente de reportes (Report Wizard), es necesario conectarse previamente a una fuente de datos, y para realizar esto, es necesario crear previamente una conexión a una fuente de datos.

Para crear una conexión a una fuente de datos para generar reportes, es necesario seguir los siguientes pasos:

  1. Presionar el botón Report Datasources, ubicado en la barra de herramientas.

  2. A continuación se muestra una ventana de diálogo que muestra las conexiones y fuentes de datos existentes. Se asumirá que aún no existe una conexión a la fuente de datos que se va a utilizar, y por lo tanto se procederá a crearla. Para ello, se hace clic en el botón New, ubicado en la parte superior derecha de la ventana.
  3. Aparece en pantalla otra ventana de diálogo, que muestra los distintos tipos de fuentes de datos. Para este caso, se elegirá el tipo de fuente más utilizado, Database JDBC Connection. Una vez seleccionado, se hace clic en el botón Next >.
  4. Luego aparecerá una tercera ventana de diálogo, que muestra las propiedades del tipo de conexión seleccionado. Es necesario darle un nombre mnemónico a la conexión. Para este caso, se llamará EjemploCon.
  5. En la misma ventana, se debe seleccionar el tipo de controlador JDBC (JDBC Driver), de acuerdo al sistema gestor de base de datos utilizado. En este ejemplo, se selecciona PostgreSQL (org.postgresql.Driver).
  6. También debe especificarse la URL de la base de datos a utilizar. En este ejemplo se utilizará la siguiente URL: jdbc:postgresql://localhost:5432/ejemplo
    En la URL de conexión a base de datos a través de JDBC, se especifica el protocolo de conexión, el subprotocolo, la dirección del servidor, el puerto y el nombre de la base de datos. En este ejemplo, estos parámetros son, respectivamente: jdbc, postgresql, localhost y ejemplo. Al utilizar la palabra localhost para especificar la dirección del servidor, se está haciendo referencia a la computadora actual, por lo que el servidor será la misma computadora desde la cual se generarán los reportes.
  7. Finalmente, debe detallarse el nombre de usuario y la contraseña, para poder acceder a la base de datos. Para este ejemplo, ambas palabras son postgres. Es posible indicar a iReports que almacene la contraseña, para evitar la molestia de ingresarla cada vez que se intente acceder a la base de datos, marcando la caja de Save password. En este ejemplo, se seleccionará la opción de recordar la contraseña, ya que no interesa la seguridad. A continuación, se ilustra mediante una captura de pantalla, la ventana de diálogo de propiedades de conexión, con todos los campos llenos:
    iReport advierte que la contraseña se almacena como texto plano, sin ninguna clase de encriptación. Por ello no se recomienda utilizar esta opción, a menos que se considere que no se requiere mayor seguridad. Si se elige no almacenar la contraseña, esta se solicitará cada vez que se intente acceder a la base de datos utilizando esta conexión.
  8. Una vez declarados todos estos parámetros, se presiona el botón de prueba (Test), para verificar que es posible realizar la conexión con los datos especificados.
  9. Si la prueba es exitosa, aparecerá el mensaje Connection test succesful!, indicando que fue posible establecer la conexión con la base de datos. En caso contrario, se mostrará un mensaje de error, indicando la posible causa de éste. Si se da esto último, es necesario verificar si los parámetros son correctos, o bien si el software servidor de bases de datos está activo y funcionando correctamente. También debe revisarse que la base de datos especificada exista, y se tengan los permisos adecuados para acceder a ella.
  10. Una vez que la conexión haya sido probada como exitosa, se hace clic en el botón Save, para que iReport guarde la nueva conexión.

Publicado originalmente el 2013-03-04, en https://itsouvenirs.wordpress.com/2013/03/04/conexion-a-fuente-de-datos-postgresql-en-ireport-3-7-3/.
Con la tecnología de Blogger.