Volviendo con un poco de angular, me salio la necesidad de crear un reloj en angular, para esto necesitamos conocer unos conceptos básicos de rxjs.
Porque usar rxjs y no un interval
Una de las maneras mas sencillas es usar un setInterval de javascript que cada segundo ejecuta una función y bueno ya tenemos un reloj, pero para no romper la armonía de angular y dejar de usar el hilo principal vamos a usar Observables y un evento llamado timer.
Como ya sabemos el Observable lo que hace es que usa un hilo asíncrono para hacer una tarea especifica y te avisa cuando existe un cambio.
timer seria como un interval en rx, le decimos cada cuanto va a ejecutarse y lo repite cada x tiempo.
como podemos ver tenemos un reloj digital para esto vamos a hacer un servicio para podernos suscribirnos y tener la información de la fecha y hora.
Creación de reloj en angular
para el servicio vamos a crear lo siguiente:
- modelo para información de datos (hora, día y fecha)
- VARIABLES Observables
- llenar variables y conversión a objeto observable
Servicio de reloj
import { Injectable } from '@angular/core';
import {timer, Observable, Subject} from 'rxjs';
import {map, shareReplay} from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class valorReloj {
hora: number;
minutos: string;
ampm: string;
diadesemana: string;
diaymes: string;
segundo: string;
}
export class XsegundoService {
clock: Observable <Date>;
infofecha$ = new Subject<valorReloj>();
vr: valorReloj;
ampm: string;
hours: number;
minute: string;
weekday: string;
months: string;
constructor() {
this.clock = timer(0,1000).pipe(map(t => new Date()),shareReplay(1));
}
getInfoReloj(): Observable<valorReloj>{
this.clock.subscribe(t => {
this.hours = t.getHours() % 12;
this.hours = this.hours ? this.hours : 12;
this.vr = {
hora: this.hours,
minutos: (t.getMinutes() < 10) ? '0' + t.getMinutes() : t.getMinutes().toString(),
ampm: t.getHours() > 11 ? 'PM' : 'AM',
diaymes: t.toLocaleString('es-MX', { day: '2-digit', month: 'long' }).replace('.', '').replace('-', ' '),
diadesemana: t.toLocaleString('es-MX', { weekday: 'long' }).replace('.', ''),
segundo: t.getSeconds() < 10 ? '0' + t.getSeconds() : t.getSeconds().toString()
}
this.infofecha$.next(this.vr);
});
return this.infofecha$.asObservable();
}
}
tenemos que recordar lo siguiente, pueden leer este articulo, pero en resumen:
- subject: que es el encargado de generar y emitir los eventos de actualización del almacén de datos.
- observable: es un objeto que permite observar los eventos emitidos por el subject.
- suscripción: generada a partir del observable.
- shareReplay: pueden suscribirse y enviara la ultima información a los suscritos para que no exista un retraso
- toLocaleString:
retorna una cadena que contiene una representación del número acorde al idioma. - next: avisa a observador que existe un cambio
- variable$: una variable con el signo $ indica que es un observable
con esto ya podemos suscribirnos en cualquier parte y poder crear un reloj en angular.
Al ser un Date, nos trae hora , minutos, segundos, fecha, dia y año, lo que hice fue un modelo y extraje lo que mas me interesaba y en formato de 12 horas.
vista del componente clock.
<div class="clock">
<p>{{dia}}</p>
<p>{{fecha}}</p>
<div class="hours">
<div class="horas">
<span class="mishoras">{{hora}}:{{minutos}}</span>
<span class="ampm">{{ampm}}</span>
</div>
</div>
<div></div>
<span></span>
<span class="segundos">{{segundos}}</span>
</div>
css
.clock {
display: grid;
grid-gap: 1px 5px;
grid-template-columns: auto auto auto;
justify-content: center;
align-content: center;
align-items: center;
align-self: center;
width: 100%;
}
.clock p {
color: #666;
font-size: 2rem;
}
.hours {
grid-column-start: 1;
grid-column-end: 3;
}
.horas {
display: flex;
flex-wrap: nowrap;
flex-direction: column-reverse;
justify-content: center;
align-items: baseline;
}
span {
color: #777777;
}
.mishoras {
font-weight: bold;
font-size: 10rem;
}
.ampm {
font-size: 1.4rem;
font-weight: 200;
}
.segundos {
width: 100%;
text-align: right;
font-size: 0.8rem;
font-size: 100;
}
Como llamar nuestro servicio para crear un reloj en angular 7
import { Component, OnInit } from '@angular/core';
import {XsegundoService, valorReloj} from '../xsegundo.service';
import { Observable } from 'rxjs';
@Component({
selector: 'app-clock',
templateUrl: './clock.component.html',
styleUrls: ['./clock.component.css']
})
export class ClockComponent implements OnInit {
datos$: Observable<valorReloj>;
hora: number;
minutos: string;
dia: string;
fecha: string;
ampm: string;
segundos: string;
constructor(private segundo: XsegundoService) { }
ngOnInit() {
this.datos$=this.segundo.getInfoReloj();
this.datos$.subscribe(x => {
this.hora = x.hora;
this.minutos = x.minutos;
this.dia = x.diadesemana;
this.fecha = x.diaymes;
this.ampm = x.ampm;
this.segundos = x.segundo
});
}
}
al ser un observable la función getInfoReloj nos regresara un cambio cada segundo (recuerden que así configuramos el timer) y para obtener el objeto que manda tenemos que suscribirnos a ellos.
al final solo llamamos a nuestro componente
<app-clock class="mreloj"></app-clock>
Como es costumbre dejare los links del repositorio y del post en live


[…] Si no reconoces o no sabes que es Subject en angular te recomiendo ver este post. […]
[…] que tenemos observables y subjects como el ejemplo pasado, estos también nos ayuda para pasar un mensaje de punto a […]