Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Introducción a servicios: crea tu primer servicio

14/23
Recursos
// 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

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

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

  1. Instalan la librería
npm i nanoid
  1. Importación
import { nanoid } from 'nanoid';
  1. Uso
const newProduct = {
      id: nanoid(4), // 4: longitud de caracteres de id
      ...payload,
    };
  1. No olviden actualizar el entity para que en vez de number sea string

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:

  • Aislar la lógica de negocio en una clase aparte
  • Reutilizar fácilmente el código de trabajo con los datos a lo largo de varios controladores

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);
}