En general los cursos de NestJs son excelentes me están gustando mucho espero creen más con todo el tema de los test.
El profesor lo explica todo muy claro.
Introducción
¿Ya tomaste el Curso de NestJS: Programación Modular?
Instalación de Docker para este curso
Instalación de Platzi Store y presentación
Database
Configuración de Docker para MongoDB
Exploración de la base de datos con Mongo Compass
Instalando y conectando MongoDB Driver
Conexión como inyectable
Ejecutando un query
Usando variables de ambiente en Mongo
Mongoose
¿Qué es Mongoose? Instalación y configuración
Implementando Mongoose en Módulos
Conectando Mongo a los servicios
Create, update y delete
Pipe para mongoid
Agregando paginación
Agregando un filtro de rango para precios
Agregando indexadores
Relaciones en MongoDB
Relaciones uno a uno embebidas
Relaciones uno a uno referenciadas
Relaciones uno a muchos embebidas
Cómo tipar relaciones uno a muchos embebidas
Relaciones uno a muchos referenciadas
Manipulación de arrays en MongoDB
Próximos pasos
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
Convierte tus certificados en títulos universitarios en USA
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Nicolas Molina
Los endpoints del tipo GET, además de paginar la información, pueden tener otro tipo de filtros más específicos para una regla de negocio. MongoDB permite crear cualquier tipo de filtro que necesite tu servicio.
Crear un filtro entre dos números X e Y que podrían ser años o precios de productos es un caso de uso bastante habitual en la consulta de datos.
Comienza creando el DTO para que el constructor reciba estos datos.
// products/products.dto.ts
import { ValidateIf } from 'class-validator';
export class FilterProductsDto {
@IsOptional()
@Min(0)
minPrice: number;
@ValidateIf((params) => params.minPrice)
@IsPositive()
maxPrice: number;
}
Utilizamos el decorador @ValidateIf()
para validar el precio máximo solo si existe el mínimo y también es válido.
Preparar el servicio para recibir estos nuevos datos y filtrar por rango mínimo y máximos un determinado campo del esquema.
// products/products.service.ts
import { Model, FilterQuery } from 'mongoose';
@Injectable()
export class ProductsService {
findAll(params?: FilterProductsDto) {
if (params) {
const filters: FilterQuery<Product> = {};
const { minPrice, maxPrice } = params;
if (minPrice && maxPrice) {
filters.price = { $gte: minPrice, $lte: maxPrice };
}
return this.productModel.find(filters).exec();
}
return this.productModel.find().exec();
}
}
Para crear el filtro de rangos máximos y mínimos, MongoDB utiliza operadores de comparaciones especiales:
De esta manera, el servicio está preparado para realizar un filtro numérico si el usuario ingresa el rango. Recuerda que este tipo de filtros suelen ser opcionales, el endpoint debe seguir funcionando correctamente en el caso de que no se ingrese un filtro.
Contribución creada por: Kevin Fiorentino (Platzi Contributor).
// src/products/dtos/products.dtos.ts
import {
...,
ValidateIf // 👈 new decorator
} from 'class-validator';
export class FilterProductsDto {
...
@IsOptional()
@Min(0)
minPrice: number; // 👈 new field
@ValidateIf((params) => params.minPrice)
@IsPositive()
maxPrice: number; // 👈 new field
}
// src/products/services/products.service.ts
import { Model, FilterQuery } from 'mongoose';
@Injectable()
export class ProductsService {
...
findAll(params?: FilterProductsDto) {
if (params) {
const filters: FilterQuery<Product> = {}; // 👈 create filters
const { limit, offset } = params;
const { minPrice, maxPrice } = params; // 👈
if (minPrice && maxPrice) {
filters.price = { $gte: minPrice, $lte: maxPrice };
}
return this.productModel.find(filters).skip(offset).limit(limit).exec();
}
return this.productModel.find().exec();
}
..
}
Aportes 9
Preguntas 6
En general los cursos de NestJs son excelentes me están gustando mucho espero creen más con todo el tema de los test.
El profesor lo explica todo muy claro.
Excelente clase, todo se entiende, todo funciona de lo más bien 😃
Cuando se didiregen a la ruta de docs para poder probar la documentación con swagger, me di cuenta que los parámetros están en
*required
, cuando estos deberian ser opcionales. En el FilterDto le agregué esto para que no sean obligatorios pasarlos. ¿Será la única solución?
export class FilterProductsDto {
@ApiProperty({ required: false })
@IsOptional()
@IsPositive()
limit: number;
@ApiProperty({ required: false })
@IsOptional()
@Min(0)
offset: number;
}
Se podría validad en ambos datos
@IsOptional()
@ValidateIf((params) => params.maxPrice)
@Min(0)
minPrice: number;
@ValidateIf((params) => params.minPrice)
@IsPositive()
maxPrice: number;
findAll(params?: FilterProductsDto) {
if (params) {
const filters: FilterQuery<Product> = {};
const limit = params.limit || 10;
const offset = params.offset || 0;
const { minPrice, maxPrice } = params;
if (minPrice && maxPrice) {
filters.price = { $gte: minPrice, $lte: maxPrice };
}
return this.productModel
.find(filters)
.skip(offset * limit)
.limit(limit)
.exec();
}
return this.productModel.find().exec();
}
Recuerden que no estamos validando que se pueda poner solamente maxPrice, el código nos deja, pero en nuestro product.service no tenemos nada de código para este caso, un ejemplo podría ser:
findAll(params?: FilterProductsDto) {
const filters: FilterQuery<Product> = {};
if (params) {
const { limit, offset, minPrice, maxPrice } = params;
if (minPrice && maxPrice) {
filters.price = { $gte: minPrice, $lte: maxPrice };
} else if (maxPrice && !minPrice) {
filters.price = { $lte: maxPrice };
}
return this.productModel.find(filters).skip(offset).limit(limit).exec();
}
return this.productModel.find().exec();
}
Recordar que cero es false en javascript, por lo tanto la condición debe ser:
if (minPrice >= 0 && maxPrice > 0) { }
excelente si en el query se envía un obejeto where para comparar con cualquier campo o atributo de la colección
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?