Usando Pipes para transformar datos

ngcontent

ng-content

Posted on April 9, 2022

Usando Pipes para transformar datos

Cuando necesitamos que nuestras aplicaciones muestren una información de una forma solamente para la visualización, en Angular podemos hacerlo gracias a los Pipes.

Angular nos permite convertir valores para ser visualizados de una manera específica sin alterarlos, en pocas palabras los Pipes nos permite tomar un dato y retornarlo transformado de la manera que queremos.

Una mala práctica comúnmente usada es utilizar un método en el template para convertirlo, para esos escenarios siempre utiliza un Pipe.

Los Pipes trabajan en conjunto con nuestros templates en los componentes utilizando el operando | obteniendo la data de izquierda a la función pipe en la derecha y esta retorna el dato transformado.

Angular viene con una lista de pipes además nos permite crear nuestras propias pipes para que retorne lo que nos interesa.

Puedes ver la lista de pipes https://angular.io/api/common#pipes

La idea en este post es usar un pipe de angular y crear uno a nuestras necesidades.

Usando el pipe currency

Suponemos que nos piden crear una interfaz en la cual muestre un listado de salarios, pero queremos ver los decimales y un formato de moneda.

salaryRanges = [
    {
      title: 'developer',
      salary: 90000,
    },
    {
      title: 'nbaPlayer',
      salary: 139883,
    },
    {
      title: 'doctor',
      salary: 72000,
    },
  ];
Enter fullscreen mode Exit fullscreen mode

Para visualizarlos en el html usamos la directiva ngFor, algo como esto.

<ul>
  <li *ngFor="let profesional of salaryRanges">
    {{ profesional.title }}
    {{ profesional.salary }}
  </li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Inicialmente se visualizan de esta forma

developer 90000
nbaPlayer 139883
doctor 72000
Enter fullscreen mode Exit fullscreen mode

Para cambiar la salida utilizando el pipe currency este por defecto utiliza USD como formato, este le agregara el símbolo de $ además de los decimales.

<ul>
  <li *ngFor="let profesional of salaryRanges">
    {{ profesional.title }}
    {{ profesional.salary | currency }}
  </li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Ahora el formato de salida sera de esta manera.

developer $90,000.00
nbaPlayer $139,883.00
doctor $72,000.00
Enter fullscreen mode Exit fullscreen mode

Perfecto, nuestros salarios se visualizan con un formato, pero que pasaria si quisiera poder convertir esos salarios a dolares o euros ? angular no tiene algo para esto... entonces creamos un Pipe custom!

Nota una solucion no optima seria llamar un metodo, en el ngFor pasandole valor y haciendo el calculo pero esto no seria optimo.

Creando el custom pipe.

Un pipe no es más que una clase de typescript que implementa la interfaz PipeTransform, vamos a crear nuestro pipe convertExchange este tomara el valor y lo divide por 55 para así hacer la conversión.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'convertExchange'
})
export class ConvertToExchange implements PipeTransform {
  transform(value: any, args?: any): any {
    return value / 55
  }
}
Enter fullscreen mode Exit fullscreen mode

Recuerda que al crear el pipe debes registrarlo en tu AppModule.

Nosotros podemos utilizar pipes anidados, por ejemplo convertExchange para generar el cálculo y currency para darle el formato.

Actualizamos nuestro html y usamos ambas pipes

{{ profesional.salary | convertToExchange | currency }}
Enter fullscreen mode Exit fullscreen mode

Y el resultado final es

developer $1,636.36
nbaPlayer $2,543.33
doctor $1,309.09
Enter fullscreen mode Exit fullscreen mode

Perfecto, nuestro pipe es capaz de convertir y darles formato, pero que pasaría si quisiéramos que el monto de cálculo sea dinámico, por ejemplo conversión de EUROS a USD.

¡Vamos a hacer ajustes!

Primero vamos a crear un objecto con el listado de monedas

const currencyValues = {
  USD: 55,
  EURO: 75,
};
Enter fullscreen mode Exit fullscreen mode

En el método transform agregamos un nuevo parámetro currency, este se utilizará para obtener el valor relacionado con la moneda y luego hacer el cálculo en el transform, en caso de que no exista lo divide entre 1.

El código final será algo como esto:

import { Pipe, PipeTransform } from '@angular/core';
const currencyValues = {
  USD: 55,
  EURO: 75,
};

@Pipe({
  name: 'convertToExchange'
})
export class ConvertToExchange implements PipeTransform {
  transform(value: any, currency: string): any {
    return value / this.getCurrencyValue(currency);
  }

  getCurrencyValue(currency) {
    return currencyValues[currency] | 1;
  }
}
Enter fullscreen mode Exit fullscreen mode

Perfecto, nuestro pipe recibirá el tipo de moneda y hará el cálculo para la conversión.

Para enviar el valor solo tenemos que usar : después del pipe.

{{ profesional.salary | convertToExchange: 'USD' | currency }}
Enter fullscreen mode Exit fullscreen mode

La salida final seria:

developer $1,636.36
nbaPlayer $2,543.33
doctor $1,309.09
Enter fullscreen mode Exit fullscreen mode

Perfect! Nuestro pipe permite recibir parámetros, pero ahora tenemos que cambiar de manera manual y si quisiéramos que el usuario elija el formato de moneda desde un select. ¡Vamos a eso!!

Un poco más interactivo.

Creamos un select con el listado de monedas para el usuario pueda seleccionar, en el evento change actualizaremos una propiedad nueva llamada currentCurrency utilizando un nuevo método llamado changeTo que por defecto será DOP que no existe, por tanto, retornara 1.

<select (change)="changeTo($any($event.target).value)">
  <option value="USD">USD</option>
  <option value="EURO">EURO</option>
  <option selected>DOP</option>
</select>
Enter fullscreen mode Exit fullscreen mode

En el componente creamos la propiedad y el método.

currentCurrency = 'DOP';
changeTo(currency) {
    this.currentCurrency = currency;
  }
Enter fullscreen mode Exit fullscreen mode

Ya lo siguiente será usar la nueva propiedad currentCurrency en el template como parámetro para nuestro pipe.

<li *ngFor="let profesional of salaryRanges">
    {{ profesional.title }}
    {{ profesional.salary | convertToExchange: currentCurrency | currency }}
  </li>
Enter fullscreen mode Exit fullscreen mode

Final

En resumen, los pipes son muy poderosos, pero te recomiendo que mires la documentación oficial de angular, donde verás muchos más ejemplos.

https://angular.io/guide/pipes

Puedes jugar con el demo del proyecto en stackbliz.

Photo by T K on Unsplash

💖 💪 🙅 🚩
ngcontent
ng-content

Posted on April 9, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related