En la parte de abajo de mi portafolio hay un reloj, el clima y un mapa. A simple vista forman una sola franja, pero cada pieza tiene su propio trabajo.
Al revisar esa parte del sitio quise cuidar algo bastante sencillo: si la consulta del clima falla, el reloj tiene que seguir marcando la hora. También quería que pedir el clima cerca de la persona que visita la página no cambiara, de paso, la zona horaria del reloj.
Parece un detalle menor. Al llevarlo al código aparecen varias preguntas: de dónde sale la hora, qué significa el punto del mapa, cuánto espero una respuesta y qué muestro mientras no tengo datos.
En la entrada anterior hablé del movimiento del hero. Esta vez me voy al otro extremo de la página, a una interacción bastante menos vistosa.
El reloj tiene una ciudad
Elegí mostrar la hora de Ciudad de México. La etiqueta de zona horaria está ahí para que no haya que adivinar si el reloj corresponde al equipo de quien visita el sitio o a mi ubicación.
La hora sale de la fecha del dispositivo y la formateo con una zona explícita. Este fragmento de la función del reloj muestra la decisión:
return new Intl.DateTimeFormat(locale === 'es' ? 'es-MX' : 'en-US', {
hour: '2-digit', minute: '2-digit', second: '2-digit',
hourCycle: 'h23', timeZone: 'America/Mexico_City'
}).format(date);
No necesito preguntarle la hora a la API del clima. El reloj se actualiza cada segundo con su propio temporizador. Eso también tiene un límite: si la fecha del dispositivo está mal, el reloj parte de ese dato. No es un servicio de sincronización de hora.
El punto del mapa representa Ciudad de México, la zona del reloj. No es una localización en vivo de la persona que está navegando.
El clima sí necesita una respuesta
Para el clima consulto Open-Meteo. Al principio uso Ciudad de México como ciudad predeterminada y muestro un estado de consulta, sin rellenar una temperatura de ejemplo.
Si llega una respuesta válida, aparecen la temperatura y las condiciones. Si no llega, la interfaz tiene que poder decirlo.
La consulta tiene un límite de ocho segundos. Además reviso que los campos que necesito tengan los tipos esperados. Una respuesta que no puedo interpretar termina en el estado de error, en lugar de convertirse en un número que parece real.
Un dato reciente no es un dato nuevo
Guardo durante diez minutos una lectura válida de la ciudad predeterminada. Si vuelvo a la página dentro de ese tiempo, puedo mostrar ese dato y aclarar que viene de la caché.
El botón de actualizar permite pedir una lectura nueva. Una entrada vencida, corrupta o con una fecha de guardado futura se descarta.
Me interesa esa diferencia entre tener un dato y saber qué estoy mostrando. La caché evita una consulta repetida, pero no quiero que parezca una actualización que acaba de ocurrir.
La ubicación se pide después de un clic
La página no solicita ubicación al entrar. Dejé un botón para pedir el clima cerca de quien la visita.
Cuando se utiliza, redondeo las coordenadas a dos decimales antes de consultar el servicio y no las guardo. Eso reduce la precisión enviada; sigue siendo una consulta de ubicación a un servicio externo, no una operación que ocurre enteramente en el equipo.
El reloj permanece en Ciudad de México. Si el permiso se rechaza, la ubicación no está disponible o falla la consulta de esa zona, el clima vuelve a la ciudad predeterminada y lo explica en su estado.
Separar esas dos decisiones evita que el mismo control cambie cosas que no prometía cambiar.
Que una respuesta vieja no gane
Hay otra situación que no se aprecia en una captura: una consulta puede seguir en camino cuando ya empecé otra.
Cada solicitud tiene un identificador. Cuando arranco una nueva, cancelo la anterior y, antes de mostrar un resultado, compruebo que siga siendo la solicitud vigente. También lo compruebo si la persona sale de la página.
Cancelar ayuda a detener trabajo pendiente. El identificador evita que una respuesta que llegó tarde reemplace el estado más reciente.
Si todo falla, el clima muestra “No disponible” y deja reintentar. El reloj mantiene su temporizador. No invento una lectura para conservar el aspecto de la franja.
Lo que me llevo de este detalle
Los dos componentes son pequeños, pero tienen dependencias muy distintas. Ponerlos juntos en el diseño no obliga a hacerlos funcionar juntos por dentro.
Las pruebas del proyecto cubren respuestas inválidas, errores HTTP y lecturas de caché recientes o vencidas. Eso ayuda a revisar el tratamiento de los datos; no equivale a haber probado cada combinación de permisos, navegador y dispositivo real.
Quise contar este caso porque es fácil concentrarse en el hero y pasar por alto el texto que aparece cuando algo no responde. También ahí se ve el cuidado de una interfaz.
Puedes revisar la franja en la portada. El botón de ubicación es opcional: el reloj ya sabe qué ciudad tiene que mostrar.
UNA IDEA PARA COMPARTIR



