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

Paginación

27/36
Recursos

Aportes 4

Preguntas 1

Ordenar por:

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

después de los 30 minutos del anterior video, este de 10 parece de 2, cuando me di cuenta ya se había terminado

Que bonito es nest

Paginación

Veamos ahora como podemos realizar paginación al momento de realizar una consulta, para esto, lo que tenemos que hacer es crear un DTO que nos permita manejar la paginación de la entidad que deseemos.

Vamos a tomar como ejemplo a nuestra entidad Products.

  • **src\products\dtos\products.dtos.ts**:
// en este caso creamos un DTO dentro del DTO de products
export class FilterProductsDto {
  @IsOptional()
  @IsPositive()
  limit: number;

  @IsOptional()
  @Min(0)
  offset: number;
}

Ahora, en nuestro controlador al utilizar los queries en el controlador, vamos a utilizar directamente el DTO que hemos creado en vez de llamarlos individualmente.

  • **src\products\services\products.service.ts**:
import {
	// ...
  Query,
} from '@nestjs/common';

// importamos el DTO del queryque queremos hacer en products
import { FilterProductsDto } from '../dtos/product.dto';

@ApiTags('products')
@Controller('products')
export class ProductsController {
  // ...
  @Get()
  // los parámetros que recibimos serán los que especificamos el en DTO
  async getProducts(@Query() params: FilterProductsDto) {
    // estos parámetros se los enviamos directamente al findAll
    return await this.productsService.findAll(params);
  }
}

De manera nativa, nuestro **findAll()** no recibe ningún parámetro, vamos a cambiar esto en nuestro servicio:

  • **src\products\services\products.service.ts**:
// ...

// importamos el DTO
import { FilterProductsDto } from '../dtos/product.dto';

@Injectable()
export class ProductsService {
  // ...

  // le especificamos que recibe un parámetro, que son las queries que le enviamos
  // este parámetro es opcional
  findAll(params?: FilterProductsDto) {
		// descontruimos los queries del params
		const { limit, offset } = params;

		return this.productRepo.find({
      relations: ['brand'],
      // para enviar el limit, lo hacemos en la propiedad "take"
      take: limit,
      // para enviar el offset, lo hacemos en la propiedad "skip"
      skip: offset,
    });
  }
}

Ahora, si lo pruebas como está de momento, nos dará un error de tipo, ya que la API siempre recibe Strings en cualquier consulta, y necesitamos números.

Para solucionar esto podemos habilitar la siguiente configuración en nuestro **main.ts**:

async function bootstrap() {
  // ...
  app.useGlobalPipes(
    new ValidationPipe({
      // ...
      // en las opciones de transformación
      transformOptions: {
        // habilitamos la conversión de parámetros de forma implicita
        enableImplicitConversion: true,
      },
    }),
  );

  // ...
}
bootstrap();

Y listo, así de fácil es hacer paginación con TypeORM.

// src\products\dtos\products.dtos.ts

// Creamos un nuevo dto
export class FilterProductDto{
  @IsOptional()
  @IsPositive()
  @ApiProperty()
  limit:number;

  @IsOptional()
  @Min(0)
  @ApiProperty()
  offset: number;
}
// src\products\controllers\products.controller.ts

@Get() 
@ApiOperation({ summary: 'List of products' })
getProducts(
	// Cambiamos la forma de recibir el parametro
  @Query() params: FilterProductDto 
) {
  return this.productsService.findAll(FilterProductDto);
}
// src\products\services\products.service.ts

// Modificamos el servicio
async findAll(params?: FilterProductDto) {
  if (params) {
    const { limit, offset } = params;

    return this.productRepo.find({
      relations: ['brand'],
      take: limit,
      skip: offset,
    });
  }

  return this.productRepo.find({
    relations: ['brand'],
  });
}
// src\main.ts
// Activamos la transformacion de forma implicita
app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,
    forbidNonWhitelisted: true,
    transformOptions: {
      enableImplicitConversion: true
    }
  }),
);