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

Resolviendo la relación muchos a muchos en el controlador

23/36
Recursos

Aportes 9

Preguntas 2

Ordenar por:

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

El .findByIds esta deprecated por lo cual se debe usar

import { In } from 'typeorm';

this.categoryRepo.findBy({id: In([1, 2, 3, 4])})

Buenas la forma correcta de revisar categoriesId en el dto es

@ApiProperty()
  @IsArray()
  @ArrayMinSize(1)
  @IsNumber({}, { each: true })
  readonly categoriesId: number[];

De esta manera te revisa que tenga al menos 1 elemento el arrray y que los elementos sean numbers

Apuntes

modificamos el dto

import {
  IsString,
  IsNumber,
  IsUrl,
  IsNotEmpty,
  IsPositive,
  IsArray,
} from 'class-validator';
import { PartialType, ApiProperty } from '@nestjs/swagger';

export class CreateProductDto {
	...

  // Agregamos este campo
  @IsArray()
  @IsNotEmpty()
  @ApiProperty()
  readonly categoriesIds: number[];

}

export class UpdateProductDto extends PartialType(CreateProductDto) {}

Create

Modificaremos el metodo para crear un producto

// src\products\services\products.service.ts
async create(data: CreateProductDto) {
    const newProduct = this.productRepo.create(data);
    if (data.brandId) {
      const brand = await this.brandRepo.findOne(data.brandId);
      newProduct.brand = brand;
    }

	// Aqui resolvemos la categoria
    if (data.categoriesIds) {
      const categories = await this.categoryRepo.findByIds(data.categoriesIds);
      newProduct.categories = categories
    }

    return this.productRepo.save(newProduct);
  }

Find

// src\products\services\products.service.ts
async findOne(id: number) {
    const product = await this.productRepo.findOne(id,{
      relations: ['brand', 'categories']
    });
    if (!product) {
      throw new NotFoundException(`Product #${id} not found`);
    }
    return product;
  }

Find of categories

// src\products\services\categories.service.ts
async findOne(id: number) {
    const category = await this.categoryRepo.findOne(id,{
      relations: ['products']
    });
    if (!category) {
      throw new NotFoundException(`Category #${id} not found`);
    }
    return category;
  }

Según este pedazo de clean code para JS; la mejor manera para hacer la parte de la consulta sin relaciones es como lo muestra Nico; pero según este pedazo, que habla sobre SOLID, es mejor tratar de dejar el servicio de productos sin inyecciones externas de código (Es decir, el repositorio); por lo que pienso que la mejor aproximación sería usar un método en el servicio Brand

Lo logré de esta forma:

const categories = await this.categoryRepository.find({
where: data.categoriesIds.map((categoryId) => ({ id: categoryId })),
});

Ya que al pasar un array en el where le estás diciendo que utilice el operador or, así no tenemos por qué importar “In” de typeorm y además podemos controlar de mejor forma la consulta.

Para el brand.service he resuelto esto; Así no importamos todo el repositorio completo nuevamente desde product.service. ```ts async findOne(id: number, withRelations: boolean = true) { const options = this.getFindOptions(withRelations) const document = await this.repo.findOne(id, options) if (!document) { this.throwDocumentNotFoundException(id) } return document } private getFindOptions(withRelations: boolean) { return withRelations ? { relations: \['products'] } : undefined } private throwDocumentNotFoundException(id: number): never { throw new NotFoundException(`Document #${id} not found`) } ```

Este cambio de código:

async findOne(id: number) {
    const category = await this.categoryRepo.findOne(id, {
      relations: ['products'],
    });
    if (!category) {
      throw new NotFoundException(`Category #${id} not found`);
    }
    return category;
  }

Lo hicimos en el SERVICIO, no en el controlador, la clase debería cambiar su título.

lo pueden hacer de esta manera TypeORM ha cambiado cositas

this.categoryRepo.findOne({
where: { id },
relations: [‘products’],
})

En caso tal estén haciendo cambios y no los vean reflejados al hacer las peticiones, deben hacer build npm run build y luego volver a correr el proyecto. Otra solución es eliminar la carpeta dist y volver a correr el proyecto.