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:

Categorías
Angular Dev TypeScript

Las cosas del Typescript

Mediocremente me robé estas cosas de un post y las voy a listar aquí para que no se me olviden. Tengo muy claro que la calidad de este post es bastante mala, que probablemente solo sea útil como autoreferencia y que el bot de google lo mirará con profundo desprecio. Ahí va:

Categorías
Angular Cloud Dev Firebase TypeScript

Como convertir un archivo .kmz a json en javascript

Como para casi cualquier cosa, existe un paquete para eso; parse2-kmz, disponible en https://www.npmjs.com/package/parse2-kmz. Utilizarlo es muy simple: