No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Aprende Ingl茅s, Programaci贸n, AI, Ciberseguridad y m谩s a precio especial.

Antes: $249

Currency
$209
Suscr铆bete

Termina en:

1 D铆as
23 Hrs
51 Min
58 Seg

Ejemplo de CRUD

17/22
Recursos

Implementaremos un peque帽o programa b谩sico que realice operaciones CRUD en un conjunto de usuarios. Este proyecto tocar谩 varios conceptos importantes de TypeScript como enums, interfaces, clases, entre otros.

Recuerda que necesitas tener Node.js instalado. Puedes descargarlo desde el sitio web oficial de Node.js.

Configurando nuestro entorno de trabajo

Haciendo empleo de la terminal y un editor de c贸digo (utilizaremos Visual Studio Code) realizaremos las configuraciones b谩sicas para poder ejecutar de manera sencilla nuestro c贸digo en TypeScript:

  1. Crea una carpeta para el proyecto
  2. Abre la carpeta del proyecto en tu editor de c贸digo de preferencia. En esta ocasi贸n usaremos Visual Studio Code y para abrirlo usando la consola, nos ubicamos en la ruta de la carpeta y ejecutamos lo siguiente:
code .
  1. Generaremos 2 archivos con los nombres .editorconfig y .gitignore dentro de la carpeta de nuestro proyecto
  2. Para autogenerar el c贸digo necesario en el archivo .gitignore nos dirigiremos a la web gitignore.io. Como par谩metros colocamos Windows, macOS, Node y Linux. Luego damos en el bot贸n 鈥淐rear鈥 o 鈥淐reate鈥 para generar el c贸digo.
  3. El c贸digo generado por esta p谩gina web lo copiaremos y lo pegaremos en nuestro archivo .gitignore
  4. En el archivo .editorconfig pega la siguiente configuraci贸n:
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
[*.md]
max_line_length = off
trim_trailing_whitespace = false> 
  1. Ahora, empecemos con la configuraci贸n b谩sica de Node. Ejecutamos lo siguiente en la ruta ra铆z de nuestra carpeta:
npm init -y
  1. Instalemos TypeScript:
npm i typescript --save-dev
  1. Generemos la configuraci贸n b谩sica para TypeScript en nuestro proyecto:
npx tsc --init
  1. Instalaremos la librer铆a ts-node para ejecutar TypeScript directamente en Node:
npm install -D ts-node
  1. En la ruta ra铆z del proyecto, crea un archivo main.ts. Este archivo tendr谩 la l贸gica de nuestro CRUD
  2. Para ejecutar el proyecto, una vez implementado, ejecutamos el siguiente comando para probarlo en la consola:
npx ts-node main.ts

Proyecto CRUD de usuarios

Ahora s铆, codifiquemos paso a paso este proyecto:

  1. Nuestros usuarios pueden tener los siguientes roles, los cuales los definiremos con un enum:
// Enum para roles de usuario
enum UserRole {
聽 聽 Admin = 'ADMIN',
聽 聽 User = 'USER'
}
  1. Definimos qu茅 estructura deber铆a tener un usuario, para ello usaremos una interfaz:
// Interfaz para la estructura de los usuarios
interface User {
聽 聽 id: number;
聽 聽 name: string;
聽 聽 email: string;
聽 聽 role: UserRole;
聽 聽 phoneNumber?: string; // Opcional
}
  1. Implementamos la clase que tendr谩 la funcionalidad CRUD y de la cual crearemos nuevos usuarios:
class UserCRUD {
聽 聽 private users: User[] = []; // Lista de usuarios

聽 聽 // Crear
聽 聽 createUser(id: number, name: string, email: string, role: UserRole, phoneNumber?: string): User {
聽 聽 聽 聽 const newUser: User = { id, name, email, role, phoneNumber };
聽 聽 聽 聽 this.users.push(newUser);
聽 聽 聽 聽 return newUser;
聽 聽 }

聽 聽 // Leer
聽 聽 getUser(id: number): User | undefined {
聽 聽 聽 聽 return this.users.find(user => user.id === id);
聽 聽 }

聽 聽 // Actualizar
聽 聽 updateUser(id: number, fieldsToUpdate: Partial<User>): User | 'Usuario no encontrado' {
聽 聽 聽 聽 const user = this.users.find(user => user.id === id);

聽 聽 聽 聽 if (!user) return 'Usuario no encontrado';

聽 聽 聽 聽 Object.assign(user, fieldsToUpdate);
聽 聽 聽 聽 return user;
聽 聽 }

聽 聽 // Borrar
聽 聽 deleteUser(id: number): 'Usuario eliminado' | 'Usuario no encontrado' {
聽 聽 聽 聽 const index = this.users.findIndex(user => user.id === id);

聽 聽 聽 聽 if (index === -1) return 'Usuario no encontrado';

聽 聽 聽 聽 this.users.splice(index, 1);
聽 聽 聽 聽 return 'Usuario eliminado';
聽 聽 }
}
  1. Finalmente, podemos hacer uso de nuestra clase UserCRUD:
// Uso de la clase UserCRUD
const userCRUD = new UserCRUD();

console.log("Usuario Creado:\n",userCRUD.createUser(1, 'Javier Paz', '[email protected]', UserRole.Admin, '333-111-888'));
console.log("Usuario Obtenido:\n",userCRUD.getUser(1));
console.log("Usuario Actualizado:\n",userCRUD.updateUser(1, { name: 'Elena D铆az' }));
console.log(userCRUD.deleteUser(1));

El c贸digo final ser铆a el siguiente:

// Enum para roles de usuario
enum UserRole {
聽 聽 Admin = 'ADMIN',
聽 聽 User = 'USER'
}

// Interfaz para la estructura de los usuarios
interface User {
聽 聽 id: number;
聽 聽 name: string;
聽 聽 email: string;
聽 聽 role: UserRole;
聽 聽 phoneNumber?: string; // Opcional
}

class UserCRUD {
聽 聽 private users: User[] = []; // Lista de usuarios

聽 聽 // Crear
聽 聽 createUser(id: number, name: string, email: string, role: UserRole, phoneNumber?: string): User {
聽 聽 聽 聽 const newUser: User = { id, name, email, role, phoneNumber };
聽 聽 聽 聽 this.users.push(newUser);
聽 聽 聽 聽 return newUser;
聽 聽 }

聽 聽 // Leer
聽 聽 getUser(id: number): User | undefined {
聽 聽 聽 聽 return this.users.find(user => user.id === id);
聽 聽 }

聽 聽 // Actualizar
聽 聽 updateUser(id: number, fieldsToUpdate: Partial<User>): User | 'Usuario no encontrado' {
聽 聽 聽 聽 const user = this.users.find(user => user.id === id);

聽 聽 聽 聽 if (!user) return 'Usuario no encontrado';

聽 聽 聽 聽 Object.assign(user, fieldsToUpdate);
聽 聽 聽 聽 return user;
聽 聽 }

聽 聽 // Borrar
聽 聽 deleteUser(id: number): 'Usuario eliminado' | 'Usuario no encontrado' {
聽 聽 聽 聽 const index = this.users.findIndex(user => user.id === id);

聽 聽 聽 聽 if (index === -1) return 'Usuario no encontrado';

聽 聽 聽 聽 this.users.splice(index, 1);
聽 聽 聽 聽 return 'Usuario eliminado';
聽 聽 }
}

// Uso de la clase UserCRUD
const userCRUD = new UserCRUD();

console.log("Usuario Creado:\n",userCRUD.createUser(1, 'Javier Paz', '[email protected]', UserRole.Admin, '333-111-888'));
console.log("Usuario Obtenido:\n",userCRUD.getUser(1));
console.log("Usuario Actualizado:\n",userCRUD.updateUser(1, { name: 'Elena D铆az' }));
console.log(userCRUD.deleteUser(1));

Contribuci贸n creada por: Mart铆n 脕lvarez (Platzi Contributor).

Aportes 46

Preguntas 3

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

tuve problema con la libreria de faker, y lo solucione de la siguiente manera:

el import entre corchetes, (ya no es default):

import {faker} from '@faker-js/faker';

y algunas props ahora estan en otros lados:

color: faker.color.human(),
tags: faker.helpers.arrayElements(),
size: faker.helpers.arrayElement(['M', 'S', 'XL', 'L']),

Para los que tuvieron errores en la implementacion de faker, yo lo resolvi de esta forma:

import {faker} from '@faker-js/faker';
import { addProduct, products } from "./products/product.service";

for (let index = 0; index < 50; index++) {
    addProduct({
        id: faker.datatype.uuid(),
        title: faker.commerce.productName(),
        description: faker.commerce.productDescription(),
        image: faker.image.imageUrl(),
        size: faker.helpers.arrayElement(['M','S','L', 'XL']),
        color: faker.commerce.color(),
        isNew: faker.datatype.boolean(),
        tags: faker.helpers.arrayElement(),
        price: parseInt(faker.commerce.price()),
        createAt: faker.date.recent(),
        updateAt: faker.date.recent(),
        stock: faker.datatype.number({min: 10, max: 100}),
        category: {
            id: faker.datatype.uuid(),
            name: faker.commerce.department(),
            createAt: faker.date.recent(),
            updateAt: faker.date.recent(),
        }
    })   
}

console.log(products)

De nada XD

ahora array elements y array element estan dentro de helpers.

faker.helpers.arrayElements(),

En caso de que se les dificulte crear la funcion de Update, Read y Delete del CRUD, ac谩 les dejo mi aporte.

Para no repetir codigo, cree el tipo Id en el archivo Base.model para mantener ese tipado mejor.

export type Id = string | number

Tambi茅n cree una funcion que retorna el index y otro que lanza un error. en el archivo product.service

const getIndex = (id: Id) => products.findIndex(product => product.id === id)
const throwError = (error: string) => new Error(error)

Ac谩 la funcion update: updateProduct

export const updateProduct = (id: Id, changes: object) => {
  const index: number = getIndex(id)
  const product: Product = products[index]
 index === -1 && throwError('Product not Found')

  products[index] = {
    ...product,
    ...changes
  }
  return products[index]
}

Ac谩 la funci贸n delete: deleteProduct

export const deleteProduct = (id: Id) => {
  const index: number = getIndex(id)
  index === -1 && throwError('Product not Found')
  products.splice(index, 1)
  return id
}

finalemnte la funcion Find: findProduct

export const findProduct = (id: Id) => {
  const index: number = getIndex(id)
  index === -1 && throwError('Product not Found')
  return products[index]
}

Espero les sirva.

Les dejo mis soluciones para las funciones getProduct(), updateProduct() y deleteProduct()
Decid铆 hacerlas por mi cuenta para ver c贸mo me iba. Primero les doy un poco de contexto de lo que us茅 y algo que cambi茅:
.

<h5>Overloading</h5>

Utilic茅 en todas las funciones overloading, ya que quise que getProduct() retornara un string si no encontraba el producto con el ID indicado.
Y las dem谩s tienen overloading ya que utilizan a getProduct()
.

<h5>Cambios en product.model.ts</h5>

Concretamente modifiqu茅 Product interface, ya que al utilizar updateProduct() no quer铆a modificar el id ni tampoco createdAt; no ten铆a sentido hacer esas modificaciones.
Entonces, Product interface cambi贸 por ProductEdit interface.
Y cre茅 un nuevo Product interface que extiende de BaseModel interface y de ProductEdit interface. Al hacer esto tuve que agregar updatedAt en ProductEdit interface y funciona todo perfecto.
.
Ahora s铆, les dejo cada funci贸n:

let products: Product[] = []; // cambi茅 el `const` por `let`


// getProduct()
function getProduct(id: string): Product;
function getProduct(id: string): string;

function getProduct(id: string): unknown {
  const product = products.find(product => product.id === id);

  return product ?? `Product with ID '${id}' does not exist.`;
}


// updateProduct()
function updateProduct(id: string, changes: ProductEdit): Product;
function updateProduct(id: string, changes: ProductEdit): string;

function updateProduct(id: string, changes: ProductEdit):unknown {
  const product = getProduct(id);

  if (product) {
    products.map(product => {
      product.id === id && Object.assign(product, changes);
    });
  }

  return product;
}


// deleteProduct()
function deleteProduct(id: string):Product;
function deleteProduct(id: string):string;

function deleteProduct(id: string):unknown {
  const product = getProduct(id);

  if (product) {
    products = products.filter(product => product.id !== id);
  }

  return product;
}

Espero les sirva馃榿

Enero de 2024, c贸digo actualizado. Les dejo los cambios que le hice a mi c贸digo guiandome de las actualizaciones de faker

import { addProduct, products } from "./products/product.services";
import { faker } from '@faker-js/faker';

for (let index = 0; index < 50; index++) {
  addProduct({
    id: faker.string.uuid(),
    description: faker.commerce.productDescription(),
    title: faker.commerce.productName(),
    image: faker.image.url(),
    createdAt: faker.date.recent(),
    updatedAt: faker.date.recent(),
    stock: faker.datatype.number({ min: 10, max: 100 }),
    color: faker.color.human(), // Corregido el m茅todo para obtener un color
    size: faker.helpers.arrayElement(['M', 'S', 'XL', 'L']), // Corregido el m茅todo para obtener un elemento aleatorio de un array
    price: parseFloat(faker.commerce.price()), // Corregido el m茅todo para obtener un precio y parsearlo a float
    isNew: faker.datatype.boolean(),
    tags: [faker.lorem.word(), faker.lorem.word(), faker.lorem.word()], // Ejemplo de tres palabras aleatorias como tags
    category: {
      id: faker.string.uuid(),
      name: faker.commerce.department(),
      createdAt: faker.date.recent(),
      updatedAt: faker.date.recent(),
    },
  });
}

console.log(products);

AQUI TE DEJO EL CODIGO PARA 2023 POR SI SE TE PRESENTA ALGUN PROBLEMA CON FAKER

import { addProduct, products } from './products/products.service'
import { faker } from '@faker-js/faker';


for (let i = 0; i < 10; i++) {
  addProduct({
    id: faker.datatype.uuid(),
    title: faker.commerce.productName(),
    description: faker.commerce.productDescription(),
    imagen: faker.image.imageUrl(),
    sizes: faker.helpers.arrayElement(['S', 'M', 'L',]),
    color: faker.color.human(),
    isNew: faker.datatype.boolean(),
    tags: faker.helpers.arrayElement(),
    precio: parseInt(faker.commerce.price()),
    createdAt: faker.date.recent(),
    updatedAt: faker.date.recent(),
    stock: faker.datatype.number({ min: 10, max: 100 }),

    category: {
      id: faker.datatype.uuid(),
      name: faker.commerce.department(),
      createdAt: faker.date.recent(),
      updatedAt: faker.date.recent(),
    }

  });
}

console.log(products);


Algunos m茅todos han cambiado de ruta en la librer铆a de faker.

En la API Reference pueden buscar cada m茅todo que no sea accesible como lo se帽ala la clase.

A fecha 19/ago/2023 hay varios modules que estan por ser obsoletos o ya lo son.

Resolv铆 de esta manera el c贸digo

import { faker } from '@faker-js/faker';

import { addProduct, products } from './products/product.service';

for (let i = 0; i < 50; i++) {
  faker.seed(i); // semilla para obtener datos consistentes

  addProduct({
    id: faker.string.uuid(),
    title: faker.commerce.productName(),
    description: faker.commerce.productDescription(),
    image: faker.image.url(),
    color: faker.color.human(),
    isNew: faker.datatype.boolean(),
    tags: faker.helpers.multiple(faker.commerce.productAdjective, {
      count: { min: 1, max: 5 },
    }),
    // Posible soluci贸n usando arrayElements
    // tags: faker.helpers.arrayElements(
    //   [
    //     faker.commerce.productAdjective(),
    //     faker.commerce.productAdjective(),
    //     faker.commerce.productAdjective(),
    //     faker.commerce.productAdjective(),
    //     faker.commerce.productAdjective(),
    //   ],
    //   { min: 1, max: 5 }
    // ),
    price: parseInt(faker.commerce.price({ min: 0, max: 150 }), 10),
    createdAt: faker.date.past(),
    updatedAt: faker.date.recent(),
    stock: faker.number.int({ min: 0, max: 100 }),
    size: faker.helpers.arrayElement(['S', 'M', 'L', 'XL']),
    category: {
      id: 1,
      name: faker.commerce.department(),
      createdAt: faker.date.past(),
      updatedAt: faker.date.recent(),
    },
  });
}

console.log(products);

Les dejo como qued贸 mi main.ts, m谩s que nada por si alguno tambi茅n tuvo problemas con ciertas funciones que estaban deprecadas o que no exist铆an en la propiedad usada.
/


/
Primero que nada el import no tiene que ser default, deber铆a ser as铆:

import { faker } from '@faker-js/faker';

/


/
Ya para el producto que vamos a crear usando faker-js hay algunas funciones que fueron colocadas en otras propiedades.

  • color, por ejemplo:
addProduct({
	...
	color: faker.commerce.color(),
	...
})

Ya no se encuentra en la propiedad commerce, sino que tiene su propia propiedad color con varias funciones. Para la clase us茅 human(), que es la misma funci贸n que ten铆a commerce.

addProduct({
	...
	color: faker.color.human(),
	...

/


/
Y as铆 con otras propiedades y/o funciones. Les dejo mi addProduct({鈥) a continuaci贸n:

addProduct({
    id: faker.datatype.uuid(),
    title: faker.commerce.productName(),
    category: {
      id: faker.datatype.uuid(),
      name: faker.commerce.department(),
      createdAt: faker.date.recent(),
      updatedAt: faker.date.recent(),
    },
    price: parseFloat(faker.commerce.price()),
    stock: faker.datatype.number({min: 10, max: 100}),
    isNew: faker.datatype.boolean(),
    image: faker.image.imageUrl(),
    description: faker.commerce.productDescription(),
    tags: faker.helpers.arrayElements(),
    size: faker.helpers.arrayElement(['S', 'M', 'L', 'XL']),
    color: faker.color.human(),
    createdAt: faker.date.recent(),
    updatedAt: faker.date.recent(),
  });

Espero les sirva 馃槃

Faker cambio la forma de utilizar arrayElement a:

faker.helpers.arrayElement(['16','S','M','L','XL'])

Con color lo mismo:

faker.color.human()
Hey soporte ! el orden de los videos est谩 mal, hay clases invertidas de posici贸n. Por favor revisen el orden de los videos.

Les dejo como lo resolv铆 con la versi贸n actual de faker:

import { faker } from '@faker-js/faker';
import { addProduct } from './products/product.service';

const randomTags = Array.from({ length: 5 }, () => faker.lorem.word());

for (let i = 0; i < 50; i++) {
  addProduct({
    id: faker.string.uuid(),
    title: faker.commerce.productName(),
    description: faker.commerce.productDescription(),
    image: faker.image.url(),
    size: faker.helpers.arrayElement(['M', 'S', 'L', 'XL']),
    color: faker.color.human(),
    isNew: faker.datatype.boolean(),
    tags: faker.helpers.arrayElements(randomTags),
    price: parseInt(faker.commerce.price()),
    createdAt: faker.date.recent(),
    updatedAt: faker.date.recent(),
    stock: faker.number.int({ min: 10, max: 100 }),
    category: {
      id: faker.string.uuid(),
      name: faker.commerce.department(),
      createdAt: faker.date.recent(),
      updatedAt: faker.date.recent(),
    },
  });
}

Actualmente faker esta en la v9.0

   addProduct({
    id: faker.datatype.uuid(),
    title: faker.commerce.productName(),
    image: faker.image.url(),
    description: faker.commerce.productDescription(),
    createAt: faker.date.recent(),
    updatedAt: faker.date.recent(),
    size: faker.helpers.arrayElement(['S', 'M', 'L', 'XL']),
    stock: faker.number.int(),
    color: faker.commerce.productMaterial(),
    price: parseInt(faker.commerce.price()),
    category:{
      id: faker.commerce.productName(),
      createAt: faker.date.recent(),
      updatedAt: faker.date.recent(),
      name: faker.commerce.productName(),
    },
    isNew: faker.datatype.boolean(),
    tags: faker.helpers.arrayElements(['new', 'used', 'N/A', 'refurbished'])
  })

Asi arregle para como se ve la libreria faker actualizada
import { addProduct, products } from 鈥./products/product.service鈥;

import { faker } from 鈥楡faker-js/faker鈥;

for (let index = 0; index < 50; index++) {
addProduct({
id: faker.string.uuid(),
descripton: faker.commerce.productName(),
image: faker.image.url(),
color: faker.color.human(),
size: faker.helpers.arrayElement([鈥淪鈥, 鈥淢鈥, 鈥淟鈥, 鈥淴L鈥漖),
price: parseInt(faker.commerce.price(), 10),
isNew: faker.datatype.boolean(),
tags: faker.helpers.arrayElements([]),
title: faker.commerce.productName(),
createdAt: faker.date.recent(),
updatedAt: faker.date.recent(),
stock: faker.number.int({
min: 10,
max: 100
}),
category: {
id: faker.string.uuid(),
name: faker.commerce.department(),
createdAt: faker.date.recent(),
updatedAt: faker.date.recent(),
}
});
}

console.log(products);
OBS: -> falto poner un generador randon en tags

Dejo la mi versi贸n con los cambios que tuve que hacer, ya que varias funciones de faker fueron depreciadas.
.
Versi贸n de Faker: "^8.0.2"
Fecha: 2023-06-19
.

import { faker } from '@faker-js/faker';

addProduct({
    id: faker.string.uuid(),
    description: faker.commerce.productDescription(),
    title: faker.commerce.productName(),
    image: faker.image.url(),
    stock: faker.number.int({ min: 10, max: 100 }),
    size: faker.helpers.arrayElement(['S', 'M', 'L', 'XL']),
    color: faker.color.human(),
    price: parseInt(faker.commerce.price(), 10),
    isNew: faker.datatype.boolean(),
    tags: faker.helpers.arrayElements(['new', 'white', 'tshirt', 'clothes']),
    createdAt: faker.date.recent(),
    updatedAt: faker.date.recent(),
    category: {
      id: faker.datatype.uuid.toString(),
      name: faker.commerce.department(),
      createdAt: faker.date.recent(),
      updatedAt: faker.date.recent(),
    },
  });

Para la versi贸n actual 8.0.2 de faker , me funcion贸 de esta manera:

addProduct({
    id: faker.datatype.uuid(),
    title: faker.commerce.productName(),
    image: faker.image.imageUrl(),
    color: faker.color.human(),
    price: parseInt(faker.commerce.price(), 10),
    isNew: faker.datatype.boolean(),
    size: faker.string.fromCharacters(["S","M","L","XL"]),
    tags: faker.random.words(5).split(" "),
    description: faker.commerce.productDescription(),
    createAt: faker.date.recent(),
    updateAt: faker.date.recent(),
    stock: faker.datatype.number({ min: 10, max: 100 }),
    category: {
      id: faker.datatype.uuid(),
      createAt: faker.date.recent(),
      updateAt: faker.date.recent(),
      name: faker.commerce.department()
    }
  });

Tuve que cambiar solamente el tipo de size ya que el tipado no me funcionaba con la opci贸n que utilice:
export interface Product extends BaseModel {
title: string;
image: string;
description: string;
stock: number;
size?: string | Size;
color: string;
price: number;
category: Category;
isNew: boolean;
tags: string[];
}

Mis metodos CRUD, me corrigen si algo esta mal, recibo retroalimentaciones 馃槂


import { Product } from './product.model';

export let products: Product[] = [];

export const addProduct = (data: Product) => {
  products.push(data);
}

export const getAllProducts =()=>{
  return products;
}
export const getProductById=(id:string)=>{
  const response =products.find(item=>item.id===id)
  return response
}
export const updateProduct = (id: string, changes: Product ) => {
  let actual=getProductById(id);
  if (actual) {
      actual.title=changes.title;
      actual.image=changes.image;
      actual.description=changes.description;
      actual.stock=changes.stock;
      actual.size=changes.size;
      actual.color=changes.color;
      actual.price=changes.price;
      actual.category=changes.category;
      actual.isNew=changes.isNew;
      actual.tags=changes.tags;
  }
  return changes;
}

export const deleteProduct=(id:string)=>{
  const product = getProductById(id);
  if(product){
    const index=products.findIndex(item=>item.id===id);
    products.splice(index,1);

  }
}

As铆 creo que podr铆a ser para delete y get (en get podemos buscar un producto por su ID o por su t铆tulo):

import { Product } from "./product.model"

export const products: Product[] = []

export const addProduct = (data: Product) => {
  products.push(data)
}

export const updateProduct = (id: string | number, changes: Product) => {

}

export const deleteProduct = (id: string | number) => {

}

export const getProduct = (id?: string | number, title?: string) => {

}

corregido en abril 2024 ```js import { faker } from '@faker-js/faker'; import { addProduct, product } from './products/product.service'; for (let index = 0; index < 50; index++) { addProduct({ id: faker.string.uuid(), description: faker.commerce.productDescription(), image: faker.image.url(), color: faker.color.human(), price: parseInt(faker.commerce.price(), 10), isNew: faker.datatype.boolean(), tags: [faker.lorem.word(), faker.lorem.word(), faker.lorem.word()], size: faker.helpers.arrayElement(['S', 'L', 'M', 'XL']), title: faker.commerce.productName(), createdAt: faker.date.recent(), updateAt: faker.date.recent(), stock: faker.datatype.number({ min: 10, max: 100 }), category: { id: faker.string.uuid(), name: faker.commerce.department(), createdAt: faker.date.recent(), updateAt: faker.date.recent(), }, }); } console.log(product); ```import { faker } from '@faker-js/faker';import { addProduct, product } from './products/product.service'; for (let index = 0; index < 50; index++) { addProduct({ id: faker.string.uuid(), description: faker.commerce.productDescription(), image: faker.image.url(), color: faker.color.human(), price: parseInt(faker.commerce.price(), 10), isNew: faker.datatype.boolean(), tags: \[faker.lorem.word(), faker.lorem.word(), faker.lorem.word()], size: faker.helpers.arrayElement(\['S', 'L', 'M', 'XL']), title: faker.commerce.productName(), createdAt: faker.date.recent(), updateAt: faker.date.recent(), stock: faker.datatype.number({ min: 10, max: 100 }), category: { id: faker.string.uuid(), name: faker.commerce.department(), createdAt: faker.date.recent(), updateAt: faker.date.recent(), }, });} console.log(product);
Para resolver el l铆o reciente con faker-js, prefer铆 utilizar una librer铆a totalmente implementada en Typescript, esta es falso`npm i @ngneat/falso` ```js npm i @ngneat/falso ```Y ya luego importas la librer铆a: ```js import { randColor } from '@ngneat/falso' ```Ya luego tienes muchas opciones para sacar un valor aleatorio de lo que sea, nombres, palabras, n煤meros etc.
Comentario de ejemplo.
Dejo mi aporte del 25 de Octubre del 2023, muchas cosas han cambiado y es mejor buscar en la documentacion, dejo lo mas actual al momento. ```js id: faker.string.uuid(), stock: faker.number.int({ min: 1, max: 100 }), title: faker.commerce.productName(), description: faker.commerce.productDescription(), image: faker.image.urlPicsumPhotos(), color: faker.internet.color(), sizes: faker.helpers.arrayElement(['S', 'M', 'L', 'XL', 'XXL']), price: parseInt(faker.commerce.price()), isNew: faker.datatype.boolean(), tags: faker.commerce.productMaterial().split(' '), createdAt: faker.date.recent(), updatedAt: faker.date.recent(), category: { id: faker.string.uuid(), name: faker.commerce.department(), createdAt: faker.date.recent(), updatedAt: faker.date.recent() } ```

para faker V8, donde muchos metodos y propiedades cambiaron

const data : productInterface =  {
      id: faker.number.int({max: 9999,}),
      title: faker.commerce.productName(),
      image: faker.image.urlLoremFlickr(),
      description: faker.commerce.productDescription(),
      price: parseInt(faker.commerce.price()),
      color: faker.color.human(),
      isNew: faker.datatype.boolean(),
      size: faker.helpers.arrayElement(['S' , 'M' , 'L' , 'XL']),
      tags: faker.helpers.multiple(faker.person.jobArea, {count:3}),
      stock: faker.number.int({min:3, max:2000}),
      createdAt: faker.date.recent(),
      updatedAt: faker.date.recent(),
      category: {
        id : faker.number.int({max: 9999,}),
        name: faker.commerce.department(),
        createdAt: faker.date.recent(),
        updatedAt: faker.date.recent(),
      }
    }
    addProduct(data);

Como ya lo mencionaron, la API de Faker ha tenido algunos cambios, aqu铆 est谩 mi addProduct y un addTags:

const addTags = () => {
  const tags: string[] = [];
  tags.push(faker.commerce.productAdjective());
  tags.push(faker.commerce.productAdjective());
  tags.push(faker.commerce.productAdjective());

  return tags;
}

//removeAllProducts()

addProduct({
  id: faker.string.uuid(),
  title: faker.commerce.productName(),
  description: faker.commerce.productDescription(),
  price: parseInt(faker.commerce.price()), //convert from string to number
  color: faker.color.human(),
  size: faker.helpers.arrayElement(['M', 'L', 'XL']),
  image: faker.image.urlLoremFlickr({category: 'commerce'}),
  createdAt: faker.date.recent(),
  updatedAt: faker.date.recent(),
  isNew: faker.datatype.boolean(0.5),
  stock: faker.number.int({min: 0, max: 99}),
  tags: addTags(),
  category: {
    id: faker.string.uuid(),
    name: faker.commerce.department(),
    createdAt: faker.date.recent(),
    updatedAt: faker.date.recent(),
  }
})

Agrego mi soluci贸n para el CRUD de la lista de Products, agregando las funciones de findProduct, updateProduct y removeProduct:

import { Product } from "./product.model";

export const products:Product[] = [];

export const addProduct = (data:Product) => {
  products.push(data);
}

export const updateProduct = (update:Product): boolean => {
  const index = products.findIndex(product => product.id === update.id)
  if(index >= 0){
    products[index] = update;
    return true;
  }
  return false;
}

export const removeProduct = (id: string | number): unknown => {
  const index = products.findIndex(product => product.id === id);
    if(index >= 0){
      let productRemoved = products[index];
      products.splice(index, 1);
      return productRemoved;
    }
  return undefined;
}

export const findProduct = (id:string | number) => {
  return products.find(product => product.id === id);
}

Actualmente aparece como deprecado datatype.uuid()
En su lugar usar :

faker.string.uuid()

Si desean que la librer铆a les genere resultados en espa帽ol pueden importarla as铆:
import { faker } from 鈥楡faker-js/faker/locale/es鈥

En lo personal cree una funcion para generar los tags:

const genTags = (): string[] => {
  const length = faker.number.int({ max: 20 });
  const tags: string[] = [];

  for (let i = 0; i < length; i++) {
    tags.push(faker.word.noun())
  }

  return tags;
};

hola hasta el momento algunas funciones de la libreria faker se sustituyeron por otras aqui por si las necesitan en este junio 2023


import { faker } from '@faker-js/faker';
import {addProduct, products} from './products/product.service';
import { Sizes } from './products/product.model';

for (let index = 0; index < 50; index++) {

	addProduct({
		id: faker.string.uuid(),
		description: faker.commerce.productDescription(),
		image: faker.image.urlLoremFlickr({ category: 'abstract' }),
		color: faker.color.human(),
		price: parseInt(faker.commerce.price()),
		isNew: faker.datatype.boolean(),
		tags: faker.helpers.arrayElements(['apple', 'banana', 'orange', 'grape', 'kiwi']),
		title: faker.commerce.productName(),
		createdAt: faker.date.recent(),
		updateAt: faker.date.recent(),
		stock: faker.number.int({min: 10, max: 100}),
		sizes: faker.helpers.arrayElement(['M','XL','S','L',]) as Sizes,
		category: {
			id: faker.string.uuid(),
			name: faker.commerce.department(),
			createdAt: faker.date.recent(),
			updateAt: faker.date.recent(),
		},
	});
}

console.log(products);

Para que faker les funcione tal cual con el c贸digo que genera el profesor, pueden trabajar con la misma versi贸n que 茅l utiliz贸 en su momento. Ejecutan el comando npm install @faker-js/faker@^6.0.0-alpha.5 para esto.

Es necesario aclarar que si ya instalaron faker pueden desinstalarlo con npm uninstall faker y luego intentar instalarla con el comando anterior.

product.service.ts

import { Product } from './product.model';

export const products: Product[] = [];

export const addProduct = (data: Product) => {
  products.push(data);
};

export const updateProduct = (id: string, newData: Product) => {
  const index = products.findIndex((product) => product.id === id);
  if (index !== -1) {
    products[index] = { ...products[index], ...newData };
  }
};

export const deleteProduct = (id: string) => {
  const index = products.findIndex((product) => product.id === id);
  if (index !== -1) {
    products.splice(index, 1);
  }
};

export const getProduct = (id: string) => {
  return products.find((product) => product.id === id);
};

export const getAllProducts = () => {
  return products;
};

Sugiero ir probando las funcionalidades con un json. Lo hace todav铆a m谩s claro. Ejemplo de product.service.ts:

import { ProductInterface } from 鈥./product.model鈥;
const fs = require(鈥榝s鈥);

export const products: ProductInterface[] = [];

export const addProduct = (input: ProductInterface) => {
products.push(input);

fs.writeFileSync(
鈥./src/app/products.json鈥,
JSON.stringify(products, null, 2)
);
};

npm install --save-dev @faker-js/faker

Ac谩 esta mi soluci贸n para el CRUD, espero que a alguien le sirva

export const addProduct = (data: Product): void => {
    products.push(data);
}
export const getProduct = (productID: string): any => {
    let product = products.filter(product => product.id === productID)
    return product
}
export const uploadProduct = (productID: string, data: object): void => {
    let newData = {...data, updatedAt: new Date() }
    let productIndex = products.findIndex(product => product.id === productID)
    Object.assign(products[productIndex], newData) 
}
export const deleadProduct = (productID: string): void => {
    let productIndex = products.findIndex(product => product.id === productID)
    products.splice(productIndex, 1)
}

En enero del 2022 paso algo curioso con el creador de la lib
Faker.js, saboteo su propio repositorio en simbolo protesta, dejo de funcionar y muchas big companies tambien se vieron afectadas, les dejo mi articulo acerca de ello, tiene muucho que ver con los ideales del opensource鈥

https://cr0wg4n.medium.com/es-un-buen-momento-para-hablar-de-ideales-en-el-mundo-del-software-f8f618a6bfb6

en las nuevas versiones usar:

faker.color.human()

en vez de: faker.commerce.color()

Aqu铆 les dejo mi funci贸n para el update:

export const updateProduct = (id: string, changes: Product) => {
  let index = products.findIndex(item => {
    id === item.id
  })

  products.splice(index, 1, changes)
}

A

OLD

faker.random.arrayElements()

NEW

faker.helpers.arrayElements()

Pocos entender谩n:

Para los tags lo implemente asi: le di un array de opciones鈥 el toma el random en cantidades y tipos y los asigna:

tags: faker.helpers.arrayElements(['perro','gato','raton','pajaro','culebra','peces','pollito']),

Por alguna raz贸n la nueva versi贸n de faker no encontre la manera de hacer un array de string, ya que el m茅todo est谩 en dataType y retorna, (string | number)[] as铆 que hice un peque帽o m茅todo para rellenar los tags, de una manera m谩s natural鈥 este fue el c贸digo que utilice

const productTagsArray = (times: number): string[] => {
  let productsArray: string[] = [];
  for(let i=0; i<times; i++){
    productsArray.push(faker.commerce.productAdjective());
  }
  return productsArray;
}

Lo agregue a product service.ts y lo importe a main.ts este es un resultado de ejemplo:

 tags: [
      'Small',      'Generic',
      'Luxurious',  'Awesome',
      'Gorgeous',   'Tasty',
      'Recycled',   'Luxurious',
      'Electronic', 'Rustic'
    ]

Librer铆a Faker

Instalaci贸n
npm install @faker-js/faker --save-dev

Importando Librer铆a
import faker from '@faker-js/faker';

Los otros templates que faltan son delete y get.

const deleteProduct = (id: string): void => {
  //code
}

const getProduct = (id: string): void => {
  //code
}
Si estas mirando este curso a d铆a de hoy te hare un gran **favor** para que evites leer la documentaci贸n a las 3:40 am buscando cuales de las cosas que coloco nico no estan deprecadas o eliminadas a d铆a de hoy **("No culpo a nico es algo habitual en el sector IT que renueven siempre las cosas y otras queden deprecadas")** ```ts addProduct({ id: faker.string.uuid(), title: faker.commerce.productName(), description: faker.commerce.productDescription(), image: faker.image.url(), price: parseInt(faker.commerce.price(), 10), isNew: faker.datatype.boolean(), tags: faker.helpers.arrayElements(faker.lorem.words({ min: 5, max: 10 }).split(' '), {min: 1, max: 10}), createdAt: faker.date.recent(), updatedAt: faker.date.recent(), stock: faker.number.int({min: 10, max: 100}), category: { id: faker.string.uuid(), createdAt: faker.date.recent(), updatedAt: faker.date.recent(), name: faker.commerce.department(), }, }) ```