Puedes crear los servicios usando el generador de Nest CLI con nest g s services/products --flat
Introducción a NestJS
¿Qué es NestJS?
Crea tu primer proyecto con NestJS
Estructura de aplicaciones en NestJS
Presentación del proyecto: Platzi Store
Repaso a TypeScript: tipos y POO
REST API
Introducción a controladores
GET: recibir parámetros
GET: parámetros query
Separación de responsabilidades
Instalación de Postman o Insomia
POST: método para crear
Métodos PUT y DELETE para editar y eliminar
Códigos de estado o HTTP response status codes
Integridad de datos
Introducción a servicios: crea tu primer servicio
Implementando servicios en tu controlador
Manejo de errores con throw y NotFoundException
Introducción a pipes: usa tu primer pipe
Crea tu propio pipe
Data Transfers Objects
Validando parámetros con class-validator y mapped-types
Evitando parámetros incorrectos
Próximos pasos
Reto: controladores y servicios restantes
Continúa con el Curso de NestJS: Programación Modular
Aún no tienes acceso a esta clase
Crea una cuenta y continúa viendo este curso
// src/entities/product.entity.ts
export class Product {
id: number;
name: string;
description: string;
price: number;
stock: number;
image: string;
}
nest g s services/products --flat
// src/services/products.service.ts
import { Injectable } from '@nestjs/common';
import { Product } from './../entities/product.entity';
@Injectable()
export class ProductsService {
private counterId = 1;
private products: Product[] = [
{
id: 1,
name: 'Product 1',
description: 'bla bla',
price: 122,
image: '',
stock: 12,
},
];
findAll() {
return this.products;
}
findOne(id: number) {
return this.products.find((item) => item.id === id);
}
create(payload: any) {
this.counterId = this.counterId + 1;
const newProduct = {
id: this.counterId,
...payload,
};
this.products.push(newProduct);
return newProduct;
}
}
// src/app.module.ts
import { Module } from '@nestjs/common';
...
import { ProductsService } from './services/products.service';
@Module({
imports: [],
controllers: [...],
providers: [AppService, ProductsService], // 👈 New Service
})
export class AppModule {}
Aportes 29
Preguntas 11
Puedes crear los servicios usando el generador de Nest CLI con nest g s services/products --flat
Bien dejo los metodos que arme para el reto, si alguno tiene algo para comparar o mejorar lo vemos!
update(id: number, payload: any) {
const productFound = this.products.findIndex((item) => item.id === id);
let message = '';
if (productFound > 0) {
this.products[productFound] = {
id: id,
...payload,
};
message = 'Product updated';
} else {
message = 'Product not found';
}
return message;
}
delete(id: number) {
const productFound = this.products.findIndex((item) => item.id === id);
let message = '';
if (productFound > 0) {
this.products.splice(productFound, 1);
message = 'product deleted';
} else {
message = 'product not found';
}
return message;
}
En TypeScript también podemos definir que una propiedad de nuestra entidad sea opcional poniendo un signo de interrogación después del nombre de la propiedad:
export class Product {
id: number;
name: string;
description: string;
price: number;
stock?: number;
image?: string;
}
Me parece interesante esta funcionalidad del lenguaje y así tenemos más opciones a la hora de crear entidades
Asi es una de las formas en las que se puede solucionar estos dos metodos 😄
update(payload: any, id: number) {
const product = this.findOne(id)
for (let key in payload) {
if (key !== 'id') {
product[key] = payload[key]
}
}
return product
}
delete(id: number) {
const product = this.findOne(id)
const productIndex = this.products.indexOf(product)
this.products.splice(productIndex, 1)
return product
}
En mi caso me gusta manejar este tipos de ID con una librería: nanoid
npm i nanoid
import { nanoid } from 'nanoid';
const newProduct = {
id: nanoid(4), // 4: longitud de caracteres de id
...payload,
};
Siguiendo con el esquema que hice en la clase de los controlares, así creo mis servicios:
nest g s modules/brand/services/brand --flat
nest g s modules/category/services/category --flat
nest g s modules/customer/services/customer --flat
nest g s modules/order/services/order --flat
nest g s modules/products/services/products --flat
nest g s modules/user/services/user --flat
Los servicios son una pieza esencial de las aplicaciones realizadas con el framework NestJS
<aside>
Están pensados para proporcionar una capa de acceso a los datos que necesitan las aplicaciones para funcionar.
</aside>
Un servicio tiene la responsabilidad de gestionar el trabajo con los datos de la aplicación, de modo que realiza las operaciones para obtener esos datos, modificarlos, etc.
Con los servicios podemos:
Para construir un servicio podemos usar el CLI de Nest. Para crear la clase de un servicio lanzamos el siguiente comando:
nest generate service products
nest g s products
Además también realiza automáticamente la modificación del archivo app.module.ts
en el que se introdujo
@Injectable
El decorador @injectable
permite inyectarse en los controladores, todo servicio debe tener este decorador antes de la declaración de la clase que lo implementa para poder usar la inyección de dependencias:
import { Injectable } from '@nestjs/common';
@Injectable()
export class ProductsService {}
edit(id: number, payload: any) {
const productEdit = this.products.findIndex((p) => p.id === id);
this.products[productEdit] = {
id: id,
...payload,
};
}
delete(id: number) {
const productDelete = this.products.findIndex((p) => p.id === id);
this.products.splice(productDelete, 1);
}
update(id: number, payload: any) {
const indexResult = this.products.findIndex((item) => item.id === id);
if (indexResult) {
const updatedItem = {
...this.products[indexResult],
...payload,
};
this.products[indexResult] = updatedItem;
} else {
throw new Error('There is not item into products');
}
}
remove(id : number) {
this.products = this.products.filter((item) => item.id != id);
}
el updateOne y deleteOne creado por mi github copilot xd:
updateOne(id: number, product: ProductEntity): ProductEntity
{
const index = this.products.findIndex((p) => p.id === id);
this.products[index] = product;
return product;
}
deleteOne(id: number): ProductEntity {
const index = this.products.findIndex((p) => p.id === id);
const product = this.products[index];
this.products.splice(index, 1);
return product;
}
A mi particularmente me gusta más declarar los modelos (esquemas de una estructura de datos sin métodos) con “type” así quedaría el typo producto:
export type Product = {
id: number;
name: string;
description: string;
price: number;
stock: number;
image: string;
};
esta es mi implementacion
private productExists(id: number) {
return this.products.some((product) => product.id == id);
}
update(payload: any, id: number) {
if (this.productExists(id)) {
this.products = this.products.map((product) => {
if (product.id == id) {
return { ...payload };
}
return product;
});
} else {
return 'Product not found';
}
}
delete(payload: any) {
if (this.productExists(payload)) {
this.products = this.products.filter((product) => product.id !== payload);
return 'Product was deleted successfully';
} else {
return 'Product not found';
}
}
Hola dejo mi sulucion, cualquier retro es bienvenida
update(id: number, payload: Product) {
let updatedProduct: Product;
this.products = this.products.map<Product>((product) => {
if (id === product.id) {
updatedProduct = { ...product, ...payload };
return updatedProduct;
}
return product;
});
return updatedProduct;
}
delete(id: number) {
this.products = this.products.filter((product) => product.id !== id);
}
Aquí dejo mi propuesta para los métodos.
update(id: number, payload: any) {
const index = this.products.findIndex((p) => p.id === id);
if(index === -1) throw Error('Not found')
this.products[index] = { id, ...payload };
}
delete(id: number) {
this.products = this.products.filter((p) => p.id !== id);
}
This is my service
import { Injectable } from '@nestjs/common';
import { Product } from 'src/entities/products/product.entity';
@Injectable()
export class ProductsService {
private counterId = 2;
private products: Product[] = [
{
id: 1,
name: 'Torta de chorizo',
description: 'Torta de chorizo de malpaso con repollo, cebolla, jitomate, aguacate y chile',
price: 40,
stock: 200,
image: null,
deleted: false,
active: true,
private: false,
},
{
id: 2,
name: 'Rufles',
description: 'Papa de sabritas sabor original, colo azul',
price: 15,
stock: 10,
image: null,
deleted: false,
active: true,
private: false,
},
];
findAll() {
return this.products;
}
findOne(id: number) {
return this.products.find((r) => r.id === id);
}
create(payload: any) {
this.counterId += 1;
const newProduct = {
id: this.counterId,
...payload,
};
this.products.push(newProduct);
return newProduct;
}
update(id: number, payload: any) {
const product = this.findOne(id);
if (product) {
const updateProduct = Object.assign(product, payload);
this.products = this.products.filter((r) => r.id !== id);
this.products.push(updateProduct);
return updateProduct;
}
return false;
}
delete(id: number) {
this.products = this.products.filter((r) => r.id !== id);
return id;
}
}
import { Injectable } from '@nestjs/common';
import { IProduct } from 'src/interfaces/product.interface';
@Injectable()
export class ProductsService {
private lastId = 0;
private products: IProduct[] = [
{
id: 1,
name: 'product 1',
price: 5,
},
];
findAll(): IProduct[] {
return this.products;
}
findOne(id: number): IProduct {
const product = this.products.find((item: IProduct) => item.id === id);
return product;
}
create(payload: IProduct) {
this.lastId++;
const newProduct: IProduct = {
id: this.lastId,
...payload,
};
this.products.push(newProduct);
return newProduct;
}
update(id: number, changes: IProduct) {
const index = this.products.findIndex((item: IProduct) => item.id === id);
const product = this.products[index];
const newData = {
...product,
...changes,
};
this.products.splice(index, 1, newData);
return {
message: 'Product updated',
newData,
};
}
delete(id: number) {
const index = this.products.findIndex((item: IProduct) => item.id === id);
this.products.splice(index, 1);
return {
message: 'Product deleted',
};
}
}
Estos son mis métodos para actualizar y borrar productos en memoria:
parecido al aporte de los compañeros
upgrade(id: number, payload: any) {
const i = this.product.findIndex((item) => item.id === id);
let message = '';
if (i !== -1) {
this.product[i] = {
id: id,
...payload,
};
message = 'Product updated';
} else message = 'Product not found';
return message;
}
delete(id: number) {
const i = this.product.findIndex((item) => item.id === id);
let message = '';
if (i !== -1) {
this.product.splice(i, 1);
message = 'Product delete';
} else message = 'Product no delete';
return message;
}
Crear o registrar nuevo producto
Metodo para retornar o buscar un solo producto
Metodo para retornar o buscar todos los productos
Crear Entidades
crear un servicio en memoria para administrarlo
Los servicios tendrán decorador especial @Injectable
Arquitectura de Nest JS
Van mis métodos.
update(id: number, payload: any) {
const targetIndex = this.products.findIndex((item) => item.id === id);
if (targetIndex > 1) {
this.products[targetIndex] = {
...this.products[targetIndex],
...payload,
};
}
}
delete(id: number) {
this.products = this.products.filter((product) => product.id !== id);
return {
deleted: id,
};
Así quedaron mis métodos
update(id: number, payload: any) {
const productArray = this.products.findIndex((item) => item.id === id);
if (productArray >= 0) {
this.products[productArray] = {
id,
...payload,
};
}
return this.products[productArray];
}
delete(id: number) {
const productArray = this.products.findIndex((item) => item.id === id);
return this.products.splice(productArray, 1);
}
Mi solucion:
update(id: number, payload: any) {
const found = this.products.findIndex((item) => item.id === id);
if (found === -1) throw new Error('Product not found');
this.products[found] = {
id: id,
...payload,
};
return {
Message: 'Product updated',
Updated: this.products[found],
};
}
delete(id: number) {
const found = this.products.findIndex((item) => item.id === id);
if (found === -1) throw new Error('Product not found');
this.products.splice(found, 1);
return {
Message: 'Product deleted',
};
}
Solución a la Tarea:
Me pareció la mejor forma. tal vez si pueda optimizarse más quedo al pendiente de sus comentarios.
update(id: number, payload: Product) {
this.products = this.products.map(product => {
if ( product.id === id ) {
const updatedProduct: Product = {
...product,
...payload
};
return updatedProduct;
}
return product;
});
}
delete(id: number) {
this.products =
this.products.filter(product => product.id !== id);
}
¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.