sábado, 29 de diciembre de 2018

martes, 25 de diciembre de 2018

domingo, 23 de diciembre de 2018

Angular: 36. Formularios. Validación por data. Creando el formulario

Vamos a preparar un nuevo formulario para empezar a ver la validación del mismo por data, es decir, que la validación de los campos la tendremos en el componente y no en el html.

miércoles, 12 de diciembre de 2018

Arduino: 2. Circuitos eléctricos básicos

Representación gráfica de circuitos

Para describir de una forma sencilla y clara la estructura y la composición de un circuito eléctrico se utilizan esquemas gráficos. En ellos se representa cada dispositivo del circuito mediante un símbolo estandarizado y se dibujan todas las interconexiones existentes entre ellos. Por ejemplo, un circuito muy simple sería:


En el esquema anterior podemos apreciar cuatro dispositivos (presentes prácticamente en cualquier circuito) representados por su símbolo convencional: una pila o batería (cuya tarea es alimentar eléctricamente al resto de componentes), una resistencia (componente específicamente diseñado para oponerse al paso de la corriente, de ahí su nombre), un LED (componente que se ilumina cuando recibe corriente) y un interruptor. En este ejemplo, la batería creará la diferencia de potencial necesaria entre sus dos extremos -también llamados "bornes" o "polos"- para que se genere una corriente eléctrica, la cual surgirá desde su polo positivo (el marcado con el signo "+"), pasará a través de la resistencia, pasará seguidamente a través del LED (iluminándolo, por tanto) y llegará a su destino final (el polo negativo de la batería) siempre y cuando el interruptor cierre el circuito.

jueves, 6 de diciembre de 2018

viernes, 30 de noviembre de 2018

domingo, 18 de noviembre de 2018

Angular: 26. Ciclo de vida de un componente

En Angular, los componentes tienen un ciclo de vida, es decir, una serie de funciones por defecto que son llamadas en un determinado momento.

Después de crear un componente/directiva llamando a su constructor, Angular llama a los métodos de enlace del ciclo de vida en la siguiente secuencia en momentos específicos:

sábado, 17 de noviembre de 2018

Angular: 25. Rutas Hijas

Ya hemos visto cómo crear un NavBar con las distintas opciones de menú de una aplicación y el sistema de navegación de rutas de la misma. Ahora vamos a ver cómo crear rutas hijas, es decir, que dentro de una opción de menú (componente) encontremos otro menú de navegación que nos permita cargar un componente u otro.
Tenemos una aplicación con la típica barra de navegación y su sistema de rutas general que permite navegar entre opciones de menú:


Vamos a utilizar el componente "principiantes" para crear un sistema de subrutas en su interior. Tenemos, como siempre, el componente "principiantes", el componente "navbar" (barra de navegación), y el fichero de rutas general (app.routes.ts):


Primero creamos varios componentes de prueba dentro del componente "principiantes", y también un nuevo fichero de rutas "principiantes.routes.ts", también dentro del componente "principiantes":


Este nuevo fichero de rutas lo informamos de la misma forma que el fichero de rutas general, pero haciendo referencia sólo a los componentes de prueba que creamos dentro del componente "principiantes":


Ahora modificamos el fichero de rutas general de la siguiente forma:


Como se puede ver, hemos añadido la etiqueta "children" en el componente "principiantes", indicando la constante con la que nombramos el fichero de subrutas del componente "principiantes".

Ahora, en el fichero html del componente "principiantes", creamos un menú lateral con botones y un contenedor con la etiqueta "router-outlet", que será donde cargaremos los componentes hijos. Como se puede ver, se hace de la misma forma que con la navegación general:


Con esto sería todo.
Por último, modificamos el fichero CSS del componente "principiantes" para aplicar estilo a los botones del menú lateral del componente. Esto no es necesario, sólo lo incluyo para que los colores del menú coincidan con los de la barra de navegación principal, pero no afecta en nada a su funcionamiento:


Ahora levantamos la aplicación, entramos en el menú de "Principiantes", y comprobamos que el menú lateral funciona correctamente, cargando el componente correspondiente al botón que pulsemos:


Y eso es todo. Podemos crear tantos sistemas de subrutas como queramos de esta manera.

domingo, 11 de noviembre de 2018

Angular: 24. Directiva NgSwitch

Vamos a ver otra directiva, la NgSwitch.

La directiva NgSwitch funciona como muchas directivas NgIf anidadas, es decir, si queremos mostrar un elemento u otro según el valor de una variable. Eso es exactamente lo que hacíamos con el NgIf, pero en éste caso nos servirá si la variable tiene más de 2 posibles valores.

Vamos a verlo con un ejemplo.

Primero creamos un componente llamado "ngSwitch" e insertamos la etiqueta de su selector en el "app.component.html" para que aparezca en pantalla.

Después creamos en el componente una variable llamada "alerta" y la informamos con el valor "info":


Después modificamos el html del componente como sigue:


Como se puede ver, hemos creado un contenedor principal con la directiva NgSwitch apuntando a la variable "alerta" del componente.
Dentro de ese contenedor principal, hemos creado 4 contenedores con la directiva NgSwitch apuntando al valor que debe tener la variable "alerta" para que ese contenedor se muestre por la pantalla. El último de los contenedores no apunta a ningún valor, será el que se muestre si el valor de la variable "alerta" no coincide con ninguno de los anteriores.

Así, como a la variable "alerta" le dimos el valor "info", se mostrará por pantalla sólo el segundo contenedor, pero podemos modificar el valor de la variable para que se muestre otro contenedor.

Para probarlo, levantamos la aplicación:


Comprobamos que se muestra sólo el contenedor "info".

Y eso es todo.

Angular: 23. Directivas personalizadas

Vamos a crear directivas personalizadas para nuestros elementos.

No sólo podemos utilizar las directivas que Angular tiene por defecto, sino que podemos crear las nuestras. Vamos a crear una directiva llamada "resaltado". Para ello, introducimos por consola el comando: "ng g d directives/resaltado":


Como podemos comprobar, el comando crea la carpeta "directives" y dentro el fichero "resaltado.directive.ts". Además, modifica el fichero "app.module.ts" con las importaciones necesarias:



Ahora vamos a utilizar la directiva. En el fichero "app.component.html" creamos un párrafo al que le introducimos la nueva directiva (mediante el selector que aparece en la clase "appResaltado", como siempre) y le pasamos un parámetro de tipo string llamado "orange" (el color naranja):


Ahora modificamos la clase de la directiva como sigue:


Como se puede ver, hay bastantes modificaciones. Vamos a verlas una a una:

Primero añadimos 3 importaciones en la primera línea. Estas importaciones son:
ElementRef: Esta importación permite hacer referencia al elemento html al que le hemos puesto la directiva, para poder utilizarlo y manipularlo.
HostListener: Esta importación sirve para añadir y utilizar manejadores de eventos, como hacer click o pasar el ratón por encima del elemento, que es el que vamos a utilizar.
Input: Esta importación sirve para que la directiva pueda recibir parámetros desde el html, como el parámetro "orange" que le estamos pasando nosotros.

Después, dentro de la clase, añadimos la línea:
@Input("appResaltado") nuevoColor:string;
Esta línea nos permite guardar en la variable "nuevoColor", el parámetro que le pasemos a la directiva por html.

Modificamos el constructor de la clase como sigue:
constructor(private el:ElementRef) {
  el.nativeElement.style.backgroundColor = "yellow";
}
Aquí, como parámetro del constructor, estamos inyectando el elemento html al que hace referencia la directiva, guardándolo en una variable "el".
Dentro del constructor, coloreamos el fondo del elemento de amarillo.

Añadimos el manejador de eventos:
@HostListener('mouseenter') mouseEntro() {
  this.resaltar(this.nuevoColor || 'yellow');
}
Esta función se lanza cuando pasamos el ratón por encima del elemento. Dentro llama a la función "resaltar" (que veremos luego) y le pasamos la variable "nuevoColor" (el color pasado por parámetro) o el color amarillo por defecto.

Añadimos el manejador de eventos:
@HostListener('mouseleave') mouseSalio() {
  this.resaltar(null);
}
Esta función se lanza cuando sacamos el ratón del elemento. Dentro llama a la función "resaltar" pasando nulo como parámetro.

Por último añadimos la función "resaltar":
private resaltar(color:string) {
  this.el.nativeElement.style.backgroundColor = color;
}
Esta función lo único que hace es cambiar el color de fondo del elemento con el color que recibe por parámetro, quitando el color si se recibe el parámetro nulo.

En resumen, lo que hace la directiva es, poner el color de fondo del elemento a amarillo por defecto, cambiarlo a naranja cuando se pasa el ratón por encima, y dejarlo sin color cuando se saca el ratón del elemento.

Levantamos la aplicación y lo probamos.

Al entrar, el color de fondo aparece en amarillo:


Al pasar el ratón por encima, se cambia a naranja:


Y al sacar el ratón, se elimina el color:


Y eso es todo.

martes, 6 de noviembre de 2018

Angular: 22. Directiva NgClass. Simular proceso asíncrono

Vamos a utilizar la directiva NgClass para simular un proceso asíncrono, siguiendo el ejemplo de la entrada anterior.

Vamos a crear un botón que cambie de estilo cuando se hace click en él para que parezca que está cargando algún proceso.

El botón va a tener un icono de guardado y un texto. Vamos a hacer que, cuando pulsemos en el botón:

1. Cambie el icono del botón.
2. Cambie el texto del botón.
3. Se desactive el botón.

Una vez que se haya terminado de ejecutar el proceso correspondiente (nosotros sólo vamos a ejecutar un proceso que no haga nada durante 3 segundos) el botón volverá a quedar como antes de hacer click en él.

Para empezar, modificamos el TypeScript como sigue:


Como se puede ver, hemos creado una variable booleana "loading" o cargando que inicializamos a falso. Luego hemos creado una función "ejecutar" que lo único que hace es poner la variable "loading" a verdadero, esperar 3 segundos, y luego volver a cambiarla a falso.

Modificamos el html como sigue:


Como se puede ver, hemos creado un botón que llama a la función "ejecutar" y cuyo atributo "disabled" depende de la variable "loading" del TypeScript.
Dentro del botón hay un icono cuya clase (imagen, por tanto) depende de la variable "loading", mostrando una clase u otra dependiendo de si la variable es verdadera o falsa.
Por último, dentro del botón también hay dos textos, en los que hemos incluido la directiva *ngIf para que se muestren o no los textos en el botón dependiendo del valor de la variable "loading".

Con esto estaría todo. Arrancamos la aplicación y el botón se debería mostrar así:


Y cuando hacemos click en el botón se mostraría así:


Pasados 3 segundos, el botón vuelve a su aspecto original. Y eso es todo.

Angular: 21. Directiva NgClass

La directiva NgClass nos permite asignar clases CSS a elementos de forma dinámica, de tal forma que podremos cambiar el estilo CSS de los elementos en cualquier momento durante la ejecución de la aplicación.

Nos creamos un componente llamado "clases", al que le creamos dos variables: un string llamado "alerta", al que le asignamos como valor "alert-danger" (una clase de Bootstrap que cambia el color a rojo). Creamos también un objeto con una propiedad booleana "danger", a la que asignamos true por defecto:


Luego modificamos el html del componente como sigue:


Como se puede ver, hemos incluido lo siguiente, de arriba a abajo:

1. Un div de tipo alert de Bootstrap, al que le incluimos la directiva NgClass y le damos el valor de la variable "alerta" del TypeScript del componente (que por defecto lo pusimos a rojo).

2. Dos botones que al hacer clic, cambian el valor de la variable "alerta" del TypeScript del componente (cambiando con ello el estilo del elemento alerta anterior).

3. Un texto "Hola Mundo" al que le incluimos la directiva NgClass, de forma que cambia la clase CSS (el color) a rojo si la variable "danger" del objeto propiedades es verdadera, y cambia el color a azul si es falsa.

4. Un botón que cambia el valor de la variable "danger" del objeto propiedades a verdadero o falso cada vez que se hace click en él. También le hemos incluido la directiva NgClass para cambiarle las clases CSS según el valor verdadero o falso de la variable "danger".

Por último, sólo queda modificar el "app.component.html" para incluir nuestro nuevo componente:


Ahora si levantamos la aplicación, se verá de la siguiente forma:


Pulsando en los diferentes botones, cambiamos el estilo CSS de los elementos de la pantalla como hemos descrito antes:


Y eso es todo.

domingo, 4 de noviembre de 2018

Angular: 20. Cambiar estilo CSS de un elemento dinámicamente

Podemos cambiar el estilo de un elemento dinámicamente. Veamos cómo hacerlo:

Creamos un proyecto nuevo. Luego creamos un componente, que llamaremos "ngStyle".
Modificamos el TypeScript del componente simplemente añadiendo una variable "numero" de valor 10, como sigue:


Ahora modificamos el html del componente como sigue:


Como se puede ver, creamos un párrafo al que añadimos "[style.fontSize.px]="tamano"".
Con esto estamos indicando que Angular se encargará de tratar el tamaño en píxeles del contenido del párrafo, y que éste será igual a la variable "tamano" del TypeScript.

Después tenemos dos botones a los que hemos añadido una función "click" que se encargará de aumentar o disminuir el valor de la variable "tamano" en 5 cada vez que hagamos click en ellos.

Por último, añadimos la etiqueta de nuestro componente  en el "app.component.html", como sigue:


Al levantar la aplicación, se muestra como sigue:


Ahora si hacemos click en el botón de más, aumentará el tamaño de letra del párrafo, y disminuirá si pulsamos en el botón de menos.

Y eso es todo.

jueves, 1 de noviembre de 2018

Angular: 19. Pipes impuros

Un Pipe impuro funciona exactamente igual que uno "normal", solo que son llamados en cada cambio del ciclo de detección, un click, el foco, el cambio del input etc, lo que significa que los datos que se muestren por pantalla van a estar siempre actualizados, cosa que puede no pasar con un Pipe "puro".



Para convertir un Pipe normal en uno impuro, simplemente añadimos "pure: false" dentro del objeto de su anotación:

import { Pipe, PipeTransform } from '@angular/core';
import { Lista } from '../../models/lista.model';

@Pipe({
  name: 'filtroCompletado',
  pure: false
})
export class FiltroCompletadoPipe implements PipeTransform {

  transform(listas:Lista[], completada:boolean) {
    return listas.filter(lista => {
      return lista.terminada === completada;
    });
  }

}

martes, 30 de octubre de 2018

lunes, 29 de octubre de 2018

Criteria Case

Para hacer un CASE deSQL en Criteria, utilizamos lo siguiente:

builderSub.selectCase().when(builderSub.equal(rootEntitySub.get("estadisticasPortabilidadId").get("tipoMensaje").get("codigo"), "SP"), rootEntitySub.get("cantidad")).otherwise(0)

Que equivale a:

CASE tipo_mensaje WHEN 'SP' THEN cantidad ELSE 0 END

domingo, 28 de octubre de 2018

Criteria Trunc Date

Para hacer un trunc de una fecha (agrupar fechas por día ('DD'), semana ('WW'), mes ('MM'), o año ('YY')) en SQL sería:

Trunc(fecha, 'MM') AS fecha

Y en Criteria sería:

builder.function("TRUNC", Date.class, rootEntity.get("fecha"), builder.literal("MM"))

sábado, 27 de octubre de 2018

Etiqueta @Formula en Entidades Hibernate y uso en Criteria

La etiqueta @Formula permite asignar una fórmula a un atributo de una entidad para que se aplique en caso de seleccionarla en alguna consulta.
Por ejemplo, tengo una entidad con un atributo "fecha" mapeado con el campo "FECHA" de la tabla de base de datos. Tengo que poder realizar una consulta a base de datos agrupando las fechas de los registros por días, semanas, meses o años dependiendo de un filtro que marcará el usuario.
En principio es tan simple como utilizar la función "TRUNC" de SQL en la consulta para que me agrupe las fechas, pero también podemos declarar el "TRUNC" en la entidad a través de la etiqueta @Formula, utilizando atributos adicionales no mapeados con ningún campo de la base de datos.

viernes, 12 de octubre de 2018

Angular: 18. Manejo de Errores

Vamos a crear un mensaje de error para mostrar cuando, eso, se produzca un error.

El funcionamiento es muy similar al del componente "cargando" de la entrada anterior. Básicamente se trata de un componente que mostraremos u ocultaremos según se haya producido o no un error.

Aunque lo más correcto sería crearnos un componente específico, tal y como hicimos con el componente "cargando", para utilizarlo en cualquier otro componente, en esta ocasión vamos a crear el mensaje directamente en el componente home, ya que es el único sitio donde vamos a mostrarlo.

Modificamos el TypeScript del componente "home" como sigue:


Como se puede ver, primero creamos dos variables. Una booleana que nos indicará si hay o no un error, y una string que guardará el mensaje de error recibido para mostrarlo por pantalla.
En el constructor, inicializamos la variable "error" booleana a falso, ya que por defecto no hay ningún error.
En la llamada al servicio de Spotify, implementamos la función del error (cuando falla la llamada al servicio) y en su interior ponemos a falso la variable del componente "cargando" (para que desaparezca de la pantalla), ponemos a verdadero la variable booleana "error", y guardamos en la variable "mensajeError" el error que nos devuelve el servicio de Spotify.

A continuación modificamos el html del componente "home" como sigue:


Como se puede ver, hemos añadido un div con un *ngIf para que aparezca sólo cuando la variable "error" sea verdadera, y mostramos la variable "mensajeError" con el contenido del error que nos devuelva el servicio.

Si se produce algún error, el mensaje se vería como sigue:


Y eso sería todo.

martes, 2 de octubre de 2018

Angular: 17. Componente Loading, o Cargando

Vamos a crear un componente para que aparezca una imagen de cargando al entrar en la página y que desaparezca cuando se haya cargado completamente.

Primero creamos un nuevo componente "loading" o el nombre que queramos:


Aunque podemos utilizar una imagen cualquiera como símbolo de "cargando", nosotros vamos a utilizar una ya creada para tal fin.
Entramos en la página "https://fontawesome.com/" y copiamos el enlace a la hoja de estilos que nos proporciona la página:


Pegamos el enlace en nuestro "index.html" tal y como hicimos con Bootstrap:


Volvemos a la página de fontawesome y buscamos iconos por "refresh". Así vemos la imagen que vamos a utilizar:


Editamos el "html" del componente "cargando" para que muestre la imagen:


Se puede ver que hemos utilizado la etiqueta <i> (propia de fontawesome) para mostrar la imagen, pero si utilizamos una propia nuestra utilizaremos la etiqueta normal "html".

Como hemos dicho antes, la idea es que la imagen se muestre en la página desde el principio y que desaparezca cuando esté toda la página cargada. Para ello, utilizaremos una variable booleana que sirva para indicar cuándo debe o no mostrarse la imagen.

Modificamos el TypeScript del componente donde queremos que aparezca la imagen como sigue:


Como se puede ver, declaramos dentro de la clase una variable booleana, que inicializamos a verdadero al principio del constructor, y cambiamos a falso al final de la función que trae los datos a la página.

Por último, en el "html" del componente donde queremos que aparezca la imagen, colocamos la etiqueta del componente "loading". Le incluimos la directiva "*ngIf" para que muestre la imagen mientras la variable booleana del componente esté a verdadero:


Y eso es todo. Al iniciar la página, la variable booleana será verdadera y se mostrará la imagen en pantalla. Una vez que todos los datos de la página estén cargados, la variable booleana cambiará de valor a falso y la imagen de carga desaparecerá.

viernes, 21 de septiembre de 2018

Angular: 16. Peticiones HTTP

Vamos a ver cómo obtener información de otro sitio web a través de una petición HTTP.

Vamos a entrar en la página "restcountries.eu", que posee un servicio de datos disponible para acceder a ellos mediante http. Vamos a buscar una lista de países cuyo idioma sea el español.
Para ello, entramos en la página, pulsamos en el menú "Language" y nos guardamos la url señalada en la imagen:


Ahora vamos a modificar el "app.module.ts" para importar el componente "HttpClientModule":



Vamos a elegir el componente "home" para capturar y mostrar los datos. Abrimos el "home.component.ts" y lo modificamos como sigue:


Como se puede ver, lo primero que hacemos es importar el "HttpClient".
Después nos creamos una variable de arrays llamada "paises".
En el constructor de la clase es donde hemos realizado la mayor modificación.
En primer lugar inyectamos en el constructor una variable "http" de la clase "HttpClient".
En segundo lugar realizamos la petición http en sí misma, haciendo un "get" de la dirección que copiamos antes de la web de países y añadiendo en el "subscribe" una función de flecha que vamos a utilizar para guardar la respuesta de la petición (la lista de países) en nuestra variable de clase "paises". Por último aprovechamos la función para mostrar a través de la consola el contenido de la respuesta.

Ahora simplemente modificamos el "home.component.html" para que muestre la lista de países mediante la directiva "*ngFor":


Y comprobamos que realmente se muestra la lista de países, y el contenido de la respuesta de la petición en la consola:


Y eso es todo.

martes, 18 de septiembre de 2018

Angular: 15. Pipes personalizados. Domseguro

Ahora vamos a crear un pipe que normalmente se utilizará para cualquier aplicación que cargue datos de otra página web, como Youtube, Spotyfy, o similares.

Primero vamos a crearnos un nuevo pipe mediante el comando "ng g p pipes/domseguro", que nos creará los ficheros necesarios.

Vamos a explicar el problema por el que necesitamos crear este pipe.
Imaginemos que queremos insertar en nuestra página un vídeo de Youtube. Para eso basta con copiar el código que nos muestra Youtube en nuestra página html:


Si copiamos el código y levantamos la aplicación, comprobaremos que el vídeo funciona perfectamente.
Ahora imaginemos que queremos crear una aplicación que recopile varios vídeos de Youtube y que muestre el vídeo que sea oportuno en cada momento. Si este es el caso, lo normal sería que, en lugar de copiar todos los códigos de los vídeos de Youtube que queremos, mostremos sólo una ventana de vídeo en la pantalla y que carguemos en ella el vídeo necesario en cada momento, guardando la ruta "src" en una variable que cogería el valor del vídeo elegido:


Como se puede ver, todos los vídeos de Youtube tienen en común como fuente la cadena "https://www.youtube.com/embed/", seguida del identificador propio del vídeo, en este caso "8vxXVhUDEwo".
Lo normal es que utilicemos una variable para guardar el identificador del vídeo ("8vxXVhUDEwo" en este caso) que concatenaremos a la ruta base ("https://www.youtube.com/embed/") en el atributo "src" de la etiqueta.
Sin embargo, si hacemos esto nos saltará un error diciendo que la ruta no es segura y no podremos ver el vídeo. Esto lo solucionaremos con nuestro nuevo pipe.

Modificaremos el pipe como sigue:


Como podemos ver, hemos importado el componente "DomSanitizer", que es el que nos permitirá marcar una ruta como segura para que no nos de error el navegador.
Después lo hemos inyectado en el constructor del pipe.
Por último, en la función del pipe en sí, devolvemos la concatenación del parámetro "url" con el valor "value" (que será "https://www.youtube.com/embed/" + "8vxXVhUDEwo") marcado como seguro.

El pipe es así de sencillo. Ahora sólo tenemos que crear en el TypeScript del componente de la página una variable que contenga el identificador del vídeo:


Y modificar el código html del vídeo como sigue a continuación para utilizar el pipe:


Y comprobamos que ahora el vídeo funciona correctamente:


Y eso es todo. A partir de ahí, simplemente podemos cambiar el valor de la variable del TypeScript para cargar cualquier vídeo en esa ventana.