Categorías
Angular

Editores de texto para Angular diferentes a TinyMCE

Opción 1. ngx-quill
es un módulo angular (>=2) para el editor de texto enriquecido Quill que contiene todos los componentes que necesita.
Más información en https://www.npmjs.com/package/ngx-quill

Opción 2. ngx-editor
Un editor de texto enriquecido simple para aplicaciones angulares creado con ProseMirror. Es un editor fácil de usar y se puede ampliar fácilmente mediante complementos de ProseMirror para crear funciones adicionales o faltantes.
Más información en https://www.npmjs.com/package/ngx-editor

Categorías
Angular Firebase Sin categoría

Cómo definir una fecha en hora local para firebase sin morir en el intento

Según Wikipedia, El tiempo universal coordinado o UTC es el principal estándar de tiempo por el cual el mundo regula los relojes y el tiempo. Es uno de los varios sucesores estrechamente relacionados con el tiempo medio de Greenwich (GMT).

Firebase entonces siempre nos entrega las horas en UTC. El problema es que si tienes alguna funcionalidad que dependa de la hora local, jamás va a coincidir la hora que Firebase te da, con la de tu zona horaria. Tendrás que procesarla antes de usarla.

A Colombia por ejemplo, le corresponde la zona horaria UTC-5 lo que quiere decir que nos encontramos 5 horas por detrás del meridiano de Greenwich. Aquí te va un ejemplo de cómo ajustar la hora para que coincida con tu hora local y no mueras en el intento:

En este ejemplo, necesito asignar a la fecha de inicio (variable inicio) el día de hoy a primera hora de la mañana (12:00:00 a.m.). Y a la fecha de fin (variable fin) el día de hoy a ultima hora del día (11:59:59 p.m.). Entonces:

Defino una variable para guardar cada una de las fechas en formato UTC que es el que me entrega Firebase. Estas variables tienen el mismo valor pero más delante las utilizaremos de diferente manera:

const inicioUtc = new Date();
const finUtc = new Date();

Seteo en cada variable las horas que necesito, de manera que la de inicio corresponda a la primera hora de la mañana y la de fin corresponda a la última de la noche:

inicioUtc.setHours(0, 0, 0, 0);
finUtc.setHours(23, 59, 59, 999);

A cada una de las fechas le sumo las 5 horas de diferencia que tenemos con la zona horaria UTC:

const inicio = new Date(inicioUtc.getTime() + 5 * 60 * 60 * 1000);
const fin = new Date(finUtc.getTime() + 5 * 60 * 60 * 1000);

Y listo!

Ten en cuenta que si haces test de manera local, las cuentas no te van a dar.

Categorías
Angular Dev TypeScript

Cómo extender la clase Error en TypeScript para manejar mejor los Errores en una aplicación

El manejo de errores es uno de los grandes faltantes en la mayoría de tutoriales disponibles en la web. Muchas veces, simplemente lanzar instancias de Error no es suficiente para poder lidiar con los diferentes tipos de Error que puede emitir una clase o una función.

Esto es aun peor cuando se consumen APIs externas, que pueden emitir muchos tipos diferentes de errores, que en cada caso habrá que manejar apropiadamente y de manera diferente.

El primer paso para lograrlo es extender la clase Error, para que pueda ser un poco más descriptiva:

export class Failure extends Error {
  public code = '';
  constructor(message: string, code: string | null = null) {
    super(message);
    if (code) {
      this.code = code;
    }
    Object.setPrototypeOf(this, new.target.prototype);
  }
}

Ahora contamos con una clase Failure, que extiende Error y que adicional nos permite tener un code, que en algunos casos es muy útil. Ahora es solo cuestión de extender dicha clase para cada uno nuestros errores:

export class NotFoundFailure extends Failure {}
export class UnknownFailure extends Failure {}

Así, en nuestro código podemos lanzar errores específicos y documentar apropiadamente nuestras funciones, indicando que también devuelven ‘never’, es decir, que podrían emitir un error. El ejemplo a continuación intenta ilustrarlo. Usen su imaginación!:

export class CosaClient {
  // ...

  /**
   * Devuelve una Cosa.
   * ...
   *
   * @throws NotFoundFailure | UnknownFailure
   */
  fetchId(id: string): Promise<Cosa | never> {
    // ...
    
    // Tirar un error!
    if (...) {
    throw new NotFoundFailure('Mensaje', '123');

    // ...

    // Tirar otro error!
    if (...) {
      throw new UnknownFailure('Mensaje', '123');
    }

    // ...
  }
}

Luego, cuando hagamos uso de la clase CosaClient, podemos saber por la documentación que emite determinados errores y hacer el manejo apropiado de ellos:

try {
  // Instanciar la clase.
  const cosaClient = new CosaClient();

  // Recuperar el ID 123.
  const cosa = CosaClient.fetchId('123');

  // ...

// Manejar los errores que puedan ocurrir en el catch.
} catch (e) {

  if (e instanceof NotFoundFailure) {
    // Decirle al usuario que ese ID no existe.

  } else if (e instanceof UnknownFailure) {
    // Decirle al usuario que ocurrió un error inesperado.

  } else if (e instanceof Error) {
    // Manejar cualquier error genérico que venga de otra parte.

  } else {
    // Manejar cualquier otra cosa inesperada.
  }
}

Finalmente, cómo nuestros propios Failures cuentan con campos para un mensaje y un código de error, podremos tener mensajes más claros y hacer un mejor manejo con las variantes de cada error.

¡Espero que esto les de ideas de como lidiar mejor con sus Errores!

Categorías
Angular Dev

RxJS Operators (operadores) para dummies

Cómo RxJS se pone bastante extraño y complejo rápidamente, aquí les comparto una explicación de coquito de varios de los operadores más usados:

https://scotch.io/tutorials/rxjs-operators-for-dummies-forkjoin-zip-combinelatest-withlatestfrom/amp

Por otra parte, les comparto un artículo con 5 usos comunes de estos operadores:

https://medium.com/grensesnittet/5-helpful-rxjs-solutions-d34f7c2f1cd9

Categorías
Angular Dev Firebase

Cómo resolver el error @firebase/firestore: Firestore (8.2.2): FIRESTORE (8.2.2) INTERNAL ASSERTION FAILED: Unexpected state en Angular con Firebase

El error @firebase/firestore: Firestore (8.2.2): FIRESTORE (8.2.2) INTERNAL ASSERTION FAILED: Unexpected state no está muy bien documentado y se presenta cuando uno esta depurando una app en Angular con Firebase, utilizando Google Chrome. Está relacionado con la opción enablePersistence y se resuelve abriendo la consola de depuración del navegador y en la pestaña Application, checkear la opción IndexedDB y borrar los datos.

Categorías
Angular Dev Firebase TypeScript

Cómo contar registros fácil y rápido en firebase

Partiendo de que ya se tenga un proyecto en Typescript con Firebase configurado, basta con crear la siguiente función:

Categorías
Angular Dev TypeScript

Sobre fechas y toLocaleDateString()

Es posible convertir un objeto Date en UTC a una fecha en hora local usando toLocaleDateString(). Toda la información de como hacerlo está aquí:

Categorías
Angular Dev Firebase TypeScript

Adaptador para un selector de fechas en Angular

Firebase entrega TimeStamps, no fechas, por lo que toca hacer la conversión respectiva. Pero es posible implementar una directiva que resuelva este problema así:

Categorías
Dev Flutter

Instalar en Android Studio para que Flutter funcione bien

Para que con flutter todo funcione bien, es necesario entrar a Android Studio, buscar en la «lupa» SDK Manager e instalar todos los SDK Tools que aparecen a continuación. No hacerlo, hará que flutter no corra bien algunos comandos. Seguramente en el momento menos apropiado.

Categorías
Angular Cloud Dev Firebase TypeScript

Cómo utilizar el emulador de Firebase sin sufrir en el intento

Este post tiene como origen divertidos problemas que hemos tenido. Recomendamos solo habilitar los Emuladores necesarios. Hemos tenido algunos líos, en especial con el Emulador Pub/Sub.

Para comenzar, es necesario tener instalado Node.js 10.13 o mayor y verificar que se tiene la última versión de firebase-tools con el siguiente comando:

npm install -g firebase-tools

Asumiendo que firebase ya está corriendo y funcionando, entonces lo siguiente es inicializar el emulador: