Introducción

1

¿Ya terminaste el Curso de NestJS: Programación Modular?

2

Platzi Store: presentación del proyecto e instalación

Database

3

Cómo instalar Docker para este proyecto

4

Configuración de PostgresSQL en Docker

5

Explorando postgres con interfaces gráficas y terminal

6

Integración de node-postgres con NestJS

7

Conexión como inyectable y ejecutando un SELECT

8

Usando variables de ambiente

TypeORM

9

¿Qué es un ORM? Instalando y configurando TypeORM Module

10

Creando tu primera entidad

11

TypeORM: active record vs. repositories

12

Crear, actualizar y eliminar

13

Cambiar a Mysql demo (opcional)

Migraciones

14

Sync Mode vs. Migraciones en TypeORM

15

Configurando migraciones y npm scripts

16

Corriendo migraciones

17

Modificando una entidad

Relaciones

18

Relaciones uno a uno

19

Resolviendo la relación uno a uno en el controlador

20

Relaciones uno a muchos

21

Resolviendo la relación uno a muchos en el controlador

22

Relaciones muchos a muchos

23

Resolviendo la relación muchos a muchos en el controlador

24

Manipulación de arreglos en relaciones muchos a muchos

25

Relaciones muchos a muchos personalizadas

26

Resolviendo la relación muchos a muchos personalizada en el controlador

Consultas

27

Paginación

28

Filtrando precios con operadores

29

Agregando indexadores

30

Modificando el naming

31

Serializar

Migración a NestJS 9 y TypeORM 0.3

32

Actualizando Dependencias para NestJS 9

33

Cambios en TypeORM 0.3

34

Migraciones en TypeORM 0.3

Próximos pasos

35

Cómo solucionar una referencia circular entre módulos

36

Continúa con el Curso de NestJS: Autenticación con Passport y JWT

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Serializar

31/36
Recursos

Aportes 6

Preguntas 5

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Serializar

Esto sirve para transformar la información antes de retórnala

// src/main.ts

// Admitimos serialiacion
app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector)));

Excluir un campo

Solo debemos agregarle el decorador @Exclude en el campo que queremos excluir

// src\users\entities\order-item.entity.ts

import { Exclude } from "class-transformer";
...
@Exclude()
@CreateDateColumn({
    type: 'timestamptz',
    default: () => 'CURRENT_TIMESTAMP',
  })
  createAt: Date;

Transformar la informacion

// src\users\entities\order.entity.ts

@Expose()
  get products() {
    if (this.items) {
      return this.items
        .filter((item) => !!item)
        .map((item) => ({
          ...item.product,
          quantity: item.quantity,
          itemId: item.id,
        }));
    }
    return [];
  }

  @Expose()
  get total() {
    if (this.items) {
      return this.items
        .filter((item) => !!item)
        .reduce((total, item) => {
          const totalItem = item.product.price * item.quantity;
          return total + totalItem;
        }, 0);
    }
    return 0;
  }

Les dejo el enlace a la documentación sobre este tema: https://docs.nestjs.com/techniques/serialization

You are the best !!! 😉

Serializar

Serializar es transformar la información que el usuario nos esta enviando antes de que nuestro controlador la retorne al servicio.

Esto nos permite hacer una serie de cosas como:

  • Excluir información
  • Agregar información
  • Trastornarla a un formato deseado

Para hacer esto, vamos a tener que ir a nuestro **main.ts** y enviar la siguiente configuración:

// importamos el reflector
import { Reflector } from '@nestjs/core';
// importamos el interceptor
import { ClassSerializerInterceptor } from '@nestjs/common';

async function bootstrap() {
  // ...

  // usamos el interceptor en la configuración global
  // añadimos una nueva instancia de la clase "ClassSerializerInterceptor" a la configuración global
  // al crear la clase, le debemos mandar el reflector, para esto lo obtenemos y lo enviamos
  app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector)));
}
bootstrap();

Con esto, ya tenemos la configuración para utilizar los interceptors en toda nuestra aplicación, ¿Pero como lo hacemos? Veamos un ejemplo:

Supongamos que deseamos excluir cuando fue creado o actualizada una orden, ya que para el cliente puede ser innecesario verlo pero para la base de datos es importante tener un registro, ¿Cómo cambiaríamos esto? Para esto vamos a nuestra entidad de **order-item** y hagamos lo siguiente:

  • **src\users\entities\order-item.entity.ts**:
// de "class-transformer", nos vamos a tarer el decorador exclude
// "class-transformer" es quien nos da los decoradores para serializar la información
import { Exclude } from 'class-transformer';

@Entity({ name: 'order_items' })
export class OrderItem {
  // ...

  // excluímos el campo deseado cuando lo retornemos
  @Exclude()
  @CreateDateColumn({
    name: 'created_at',
    type: 'timestamptz',
    default: () => 'CURRENT_TIMESTAMP',
  })
  createdAt: Date;

  // excluímos el campo deseado cuando lo retornemos
  @Exclude()
  @UpdateDateColumn({
    name: 'updated_at',
    type: 'timestamptz',
    default: () => 'CURRENT_TIMESTAMP',
  })
  updatedAt: Date;
}

Bien, ahora veamos como podemos modificar un dato antes de enviarlo. Digamos que deseamos transformar el Array de las ordenes antes de que lo enviemos, por ejemplo, si queremos hacer que el resultado de nuestra petición sea mucho más limpia podemos hacer que los items de la orden sean solo un array de productos y que nos dé el precio total de la orden de compra. Para realizar esto debemos utilizar el decorador **@Expose()**.

  • **src\users\entities\order.entity.ts**:
// importamos decoradores
import { Expose, Exclude } from 'class-transformer';

@Entity({ name: 'orders' })
export class Order {
  // ...

  // esto lo tenemos que excluír para que no duplique campos
  @Exclude()
  @OneToMany(() => OrderItem, (item) => item.order)
  items: OrderItem[];

  // decorador para "crear nuevos datos"
  @Expose()
  get products() {
    // tenemos items?
    if (this.items) {
      // hacemos esta transformación

      return this.items
        .filter((items) => !!items) // nos aseguramos que no sea nulo o oundefined
        .map((item) => ({
          // recorremos todos los items
          ...item,
          // le añadimos el campo "quantity" al producto
          quantity: item.quantity,
					// añadimos el identificador del item
          itemId: item.id,
        }));
    }

    return [];
  }

  // podemos crear un campo donde nos de el precio total de la orden
  @Expose()
  get total() {
    // tenemos items?
    if (this.items) {
      // hacemos esta transformación

      return this.items
        .filter((items) => !!items) // nos aseguramos que no sea nulo o oundefined
        .reduce((acum, item) => {
          // el precio total es igual a el precio por la cantidad
          const totalItem = item.product.price * item.quantity;
          // se lo sumamos al acum en cada iteración
          return acum + totalItem;
        }, 0);
    }

    return 0;
  }
}

Y listo, ya sabes usar una de las técnicas más útiles que tiene una API para manipular la información que le retorna al usuario. Sin embargo tienes que tener cuidado como manejas esta información porque hacer demasiados cálculos puede afectar negativamente el rendimiento de la app.

Uff, qué bello ese reduce 🗿 🚬

👏