No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

No se trata de lo que quieres comprar, sino de quién quieres ser. Aprovecha el precio especial.

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

14 Días
9 Hrs
21 Min
23 Seg

Eliminar productos del carrito

19/31
Recursos

Aportes 27

Preguntas 0

Ordenar por:

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

Yo le quise poner un contador de unidades, para que pueda comprar mas de uno, y cuando guardo el producto del carrito le agrego una propiedad units al objeto para saber cuantas unidades cquiere comprar

aca parte del codigo :

 const sumOrRestItem =(id, action)=>{
    const newProducts = [...cartProducts]
    const itemIndex = newProducts.findIndex(product => product.id === id)
    if(action=='minus'){
      newProducts[itemIndex].units--
      setCartProducts(newProducts)
    }
    else if(action=='plus'){
      newProducts[itemIndex].units++
      setCartProducts(newProducts)
    }
    if(newProducts[itemIndex].units == 0){
      deleteItem(id)
    }
  }

Para mostrar la cantidad de items del carrito en NavBar, decidí eliminar del context

  const [count, setCount] = useState(0);

y simplemente reemplazarlo por

 { context.productsInCart.length }

del mismo context. De esta forma, no tengo que aumentar o disminuir la cantidad cada vez que se agrega o elimina un producto del carrito

Le agregue un poco para que cuando se elimine un producto el contador del carrito disminuya tambien:

const deleteProduct = (id) =>{
    const filteredProducts = context.cartProducts.filter(product => product.id != id)
    context.setCartProducts(filteredProducts)
    context.setCounter(context.counter - 1)
  }

Agregue estas clases adicionales para hacer la grilla responsive en el div que contiene todas las Cards:

'grid-cols-auto justify-items-center sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'

Le agregue titulos a las columnas, botones de agregar y reducir cantidad de los items y una columna de subtotal que se actualiza junto a la cantidad.

Les comparto el codigo de los metodos usados en el carrito

// ADD PRODUCTS TO CART
    const addProductToCart = (event, item) => {
        event.stopPropagation();
        closeProductDetail();
        closeShoppingCart();
        setCounter(counter + 1);
        const productIndex = cartProducts.findIndex(product => product.id === item.id)
        let newCart = []
        if (productIndex >= 0) {
            newCart = [...cartProducts]
            newCart[productIndex].quantity++
            newCart[productIndex].subtotal = newCart[productIndex].price * newCart[productIndex].quantity
            
        } else {
            newCart = [...cartProducts, { ...item, quantity: 1, subtotal: item.price }]
        }
        setCartProducts(newCart);
    }

    // DELETE PRODUCT OF CART
    const deleteProductOfCart = (id) => {
        const productIndex = cartProducts.findIndex(product => product.id === id);
        const quantity = cartProducts[productIndex].quantity
        const newCart = cartProducts.filter(product => product.id != id);
        setCounter(counter - quantity);
        setCartProducts(newCart);
    }

    // ADD QUANTITY OF ITEM IN CART
    const plusQuantity = (id) => {
        const productIndex = cartProducts.findIndex(product => product.id === id);
        let newCart = [...cartProducts];
        newCart[productIndex].quantity++;
        newCart[productIndex].subtotal = newCart[productIndex].price * newCart[productIndex].quantity
        setCounter(counter + 1);
        setCartProducts(newCart);
    }

    // DECREASE QUANTITY OF ITEM IN CART
    const lessQuantity = (id) => {
        const productIndex = cartProducts.findIndex(product => product.id === id);
        let newCart = cartProducts
        if (newCart[productIndex].quantity > 1) {
            newCart[productIndex].quantity--;
            newCart[productIndex].subtotal = newCart[productIndex].price * newCart[productIndex].quantity
            setCounter(counter - 1);
            setCartProducts(newCart);
        } else {
            alert("La cantidad de este item es 1, debes eliminarlo si ya no lo deseas");
        }
    }

Agregue la cantidad de productos en el titulo del CheckoutSideMenu.jsx

.

<div className="flex justify-between items-center pb-6 px-2">
        <h2 className="font-medium text-xl">My Order 
            <span className="font-normal text-base">({cartProducts.length} {cartProducts.length > 1 ? 'products' : 'product'})</span>
        </h2>
        <XCircleIcon
          className="h-6 w-6 text-gray-500 cursor-pointer hover:text-red-600 transition-all"
          onClick={() => closeCheckoutSideMenu()}
        />
      </div>
No entendía por qué no se cerraba el objeto seleccionado: 1\) 2h viendo el video de 5' 🤓 2\) revise bien y resulta que en algunas líneas de todos los index.jsx puse "card" en vez de "cart" 😭. Ej: setCardProducts 3\) casi me pego 5 tiros en la rodilla 😫
yo adicionalmente le puse el decrementador del conteo del navbar cada vez que se elimina un producto y un closeCheckoutSideMenu() cada vez que se eliminen todos los productos. Todo en el handleDelete ```js const handleDelete = (id) => { const filteredProducts = shoppingCart.filter((product) => product.id != id) setShoppingCart(filteredProducts) setCounter(counter - 1) if (filteredProducts.length < 1) closeCheckoutSideMenu() } ```const handleDelete = (*id*) => {    const filteredProducts = shoppingCart.filter((*product*) => *product*.id != *id*)     setShoppingCart(filteredProducts)    setCounter(counter - 1)     if (filteredProducts.length < 1) closeCheckoutSideMenu()  }

Usé otra API, pero igual puede servir, los nombres a veces estan muy largos y no quedaban bien, y cuando son muy cortos, no quedan bien alineados frente al precio en el grid de los productos

Entonces está fue mi solución:

Falto decrementar el valor del contador al eliminar el producto del carrito 😁

En el componente CheckOuteSideMenu funcion handleDelete agregue el contexto setcount para que vaya contando los elementos eliminados: ```js const handleDelete = (id) => { const filterProducts = context.cartProducts.filter(product => product.id != id) context.setcartProducts(filterProducts) context.setCount(context.count - 1) } ``` const handleDelete = (id) => {    const filterProducts = context.cartProducts.filter(product => product.id != id)    context.setcartProducts(filterProducts)    context.setCount(context.count - 1)  }
## 🦄✨Para fines prácticos y de UX, declaré la función de eliminar productos del carrito en el contexto, esto con el fin de que se pueda eliminar cuando se da click en el trashIcon o cuando se da click en el checkIcon de la Card. ![](https://static.platzi.com/media/user_upload/image-25bee371-be4b-4e14-a4d0-19237aca18c4.jpg) Adicional. Cambié la función de incrementCounter, por una llamada updateCounter, que actualizará el valor del contador del carrito cada que se añada o elimine algún producto del checkout. ![](https://static.platzi.com/media/user_upload/image-fe38a9d1-0ea7-4eae-b4c5-e45c5463ff02.jpg) ![](https://static.platzi.com/media/user_upload/image-62197734-66e7-4115-b435-aa8410a124a2.jpg)
Hola! Me he pasado mucho rato viendo por qué es que no me funciona el cambio de botón de agregar a ckeck según el id. Estuve probando si es que reconoce el id y lo imprime todo ok. Puede ser que la extensión Prettier haga algo? veo ligeras diferencias en la sintaxis cuando guardo
En lugar de usar solamente != se recomienda usar !==
Añadí dentro del handleDelete el setCount para actualizar el estado del contador a un lado de la bolsa de compras en el navbar . Mi pequeño aporte. ```js const handleDelete = (id) => { const filteredProducts = productsToBuy.filter( (product) => product.id != id ); setProductsToBuy(filteredProducts); setCount(count - 1); }; ```
Hago mi humilde aporte <u>para agregar varios elementos iguales a la orden de compra</u> *Primero enviar los **cartProducts** con la propiedad quantity* ```js const addProductsToCart = (e, product) => { e.stopPropagation(); setCount(count + 1) const idsInCart = cartProducts.map((element) => (element.id)) const isIdExisting = idsInCart.includes(product.id) const indexProduct = cartProducts.findIndex(element => element.id === product.id) console.log(indexProduct, "index") //en esta parte=> if (!isIdExisting) { product.quantity = 1; setCartProducts([...cartProducts, product]) } else { const updatedCartProducts = [...cartProducts]; updatedCartProducts[indexProduct].quantity += 1; setCartProducts(updatedCartProducts); } } ```   *Luego **orderCard** se ve de esta forma con un selector que envia eventos que disparan funciones que modifican a product cart.* ```js const OrderCard=(props)=>{ const { setCartProducts, cartProducts } = useContext(ShoppingCartContext) const {id,imageUrl,title,price,quantity}=props; const indexProduct = cartProducts.findIndex(element => element.id === id) const updatedCartProducts = [...cartProducts]; const updateQuantity= ({id,num})=>{ updatedCartProducts[indexProduct].quantity = num; setCartProducts(updatedCartProducts); } const deleteProductInCart=(id)=>{ updatedCartProducts.splice(indexProduct,1); console.log(updatedCartProducts,"asdas") setCartProducts(updatedCartProducts); } return(

{title}

<select value={quantity} onChange={(e) => {updateQuantity({id,num:parseInt(e.target.value)})}} > {Array.from({ length: 10 }, (_, index) => ( <option key={index} value={index + 1}>{index + 1}</option> ))} </select>
deleteProductInCart(id)}> <CloseIcon h='6' w='6'/>

${price*quantity}

) } ```*Pero el problema lo tuve cuando en el carrito del navBar (el **SETCOUNT**) ya no me servia en hacer sumas o restas porque es muy dificil ordenar dentro de un componente (**orderCard**) de que forma se comporta ya que se esta renderizando muchas veces. Entonces lo que se me ocurrio fue trabajar en el context y se termino viendo asi:* ```js const updateQuantityInIconCart=()=>{ let numOfClothes=0 cartProducts.map(element=> numOfClothes+=element.quantity) setCount(numOfClothes) } useEffect(() => { updateQuantityInIconCart(); }, [cartProducts]); ```*Al principio mandaba **updateQuantityInIconCart**() dentro del los eventos de agregar y eliminar productos del aside. Pero por alguna razon seguramente de orden de renderizado **deleteProductInCart (){updateQuantityInIconCart()** } no funcionaba correctamente.* *Entonces recorde que la segunda propiedad de useEffect detecta cambios y se ejecuta, Y aclaro no se si esta bien usado pero fue lo que se me ocurrio. Ojala les sirva saludos ('.')/*
![](https://static.platzi.com/media/user_upload/image-25c44025-9bf8-4403-be55-3668b900124b.jpg)yo tambien coloque un contador de undidades por productos
```ts // ORDERCARD.TSX import { XMarkIcon } from "@heroicons/react/24/solid" import { Items } from "../../Global/globalConst" export const OrderCard = ({ id, title, price, image, handleDelete }: Items): JSX.Element => { return (

{title}

${price}

<XMarkIcon className='h-6 w-6 cursor-pointer' onClick={() => handleDelete({ id })} />
) } ``` ```js //checkOutSideMenu.tsx import { useShoppingContext } from '../../Context/Context'; import { XMarkIcon } from '@heroicons/react/24/solid'; import { OrderCard } from '../OrderCard/OrderCard'; import { Items } from '../../Global/globalConst'; import './checkOutSideMenu.css'; export const CheckOutSideMenu = (): JSX.Element => { const { isCheckoutSideMenuOpen, closeCheckOutMenu, cartProducts, setCartProducts } = useShoppingContext(); const closeCheckOutModal = () => { closeCheckOutMenu(); } const handleDelete = (productCart: Items): void => { const filteredProducts = cartProducts.filter(product => product.id != productCart.id) setCartProducts(filteredProducts) } return ( <aside className={`${isCheckoutSideMenuOpen ? 'checkout-side-menu flex flex-col fixed right-0 border border-black rounded-lg bg-white' : 'hidden'}`} >

My Order

<XMarkIcon className='h-6 w-6 cursor-pointer' onClick={closeCheckOutModal} />
{cartProducts.map((product) => <OrderCard key={product.id} {...product} handleDelete={handleDelete} /> )}
</aside> ) } ```
Hola Teff ha si voy en mi e-commerce espero comentarios ![]()gracias: ![]()![]("C:\Users\Hp\Downloads\19.11.2023-11_44.gif")

Mi contador lo dejé de esta forma

En mi caso hice lo siguiente:

.
Primero, en el componente Card a los objetos del carrito les aumenté la propiedad quantity que por defecto será igual a 1.

addProductToCart(event, { ...data, quantity: 1 })

.
En el componente OrderCard tengo lo siguiente:

import { MinusIcon, PlusIcon } from "@heroicons/react/24/solid";
import { useContext } from "react";
import { ShopiCartContext } from "../../Context";

const OrderCard = ({ product, handleDelete }) => {
  const { id, title, images, price, quantity } = product;
  const { cartProducts, setCartProducts } = useContext(ShopiCartContext);

  const addItem = (id) => {
    const updatedCartProducts = cartProducts.map((product) => {
      if (product.id === id) {
        return { ...product, quantity: product.quantity + 1 };
      }
      return product;
    });

    handleDelete(id);
    setCartProducts(updatedCartProducts);
  };

  const removeItem = (id) => {
    if (quantity === 1) {
      handleDelete(id);
    } else {
      const updatedCartProducts = cartProducts.map((product) => {
        if (product.id === id) {
          return { ...product, quantity: product.quantity - 1 };
        }
        return product;
      });

      handleDelete(id);
      setCartProducts(updatedCartProducts);
    }
  };

  return (
    <div className="flex justify-between item-center mb-3">
      <div className="flex items-center w-full justify-between gap-2">
        <figure className="w-20 h-20">
          <img
            className="w-full h-full rounded-lg object-cover"
            src={images}
            alt={title}
          />
        </figure>
        <div className="flex-grow w-[80px] flex flex-col items-end pr-3">
          <p className="text-lg font-medium text-end">{price * quantity}</p>
          <p className="text-sm font-light text-end">{title}</p>
        </div>
      </div>
      <div className="flex items-center gap-2">
        <MinusIcon
          className="h-4 w-4 text-black cursor-pointer"
          onClick={() => removeItem(id)}
        ></MinusIcon>
        <span className="bg-slate-200 rounded-md">{quantity}</span>
        <PlusIcon
          className="h-4 w-4 text-black cursor-pointer"
          onClick={() => addItem(id)}
        ></PlusIcon>
      </div>
    </div>
  );
};

export default OrderCard;

He creado los iconos correspondientes a disminuir y aumentar la cantidad de un producto. Si al disminuir la cantidad de un ítem llega a 0 lo elimino.
.
El precio que se muestra será igual al precio * la cantidad.
.
Tanto al aumentar como al disminuir la cantidad de un ítem, lo que se hace es obtener un nuevo array con el item con la cantidad modificada updatedCartProducts. Eliminamos el ítem del carrito mediante la función handleDelete(id) y modificamos el carrito con el nuevo array mediante setCartProducts(updatedCartProducts).

const handleDeleteProductCart = (id) =>{
        const products = [...cartProducts]
        products.map((product,index) =>{
            if(product.id === id){
                product.count--;
                if(product.count === 0){
                    products.splice(index,1)
                }
            }
        } );
        setCartProducts(products);
    }

    const sumCountProductCart = (id) =>{
        const products = [...cartProducts]
        products.map((product,index) =>{
            if(product.id === id){
                product.count++;
            }
        } );
        setCartProducts(products);
    }

En mi caso defini la funcion handleDelete dentro del componente OrderCard y no en el CheckoutSideMenu

como agregue cantidades para poder tener varios items del mismo para borrarlos del carrito de navbar usé este code:

const CheckoutSideMenu = () => {
    const { 
        isCheckoutSideMenuOpen,
        closeCheckoutSideMenu, 
        cartProducts, 
        setCartProducts, 
        setCount,
     } = useContext(ShoppingCartContext);

    const handleDelete = (id) => {
        const filteredProducts = cartProducts.filter(product => product.id != id);
        setCount(cartProducts.length - 1)
        setCartProducts(filteredProducts)
    }

Para quitar el siguiente mensaje en el archivo OrderCard/index.jsx:
‘id’ is missing in props validation

Deben instalar propTypes:

npm install --save prop-types

De ahí, pongan el import en la parte superior:

import PropTypes from 'prop-types';

Por último, en seguida de return (todo el código de div), agregan lo siguiente:

OrderCard.propTypes = {
  id: PropTypes.node.isRequired,
  title: PropTypes.node.isRequired,
  imageUrl: PropTypes.node.isRequired,
  price: PropTypes.node.isRequired,
  handleDelete: PropTypes.node.isRequired,
};

Me funcionó a mí a quitar esos mensajes molestos.

Yo hice estas funciones para poder, mostrar los productos sin que se repitan las cards, aumentar, disminuir y eliminar todos los productos de la orden que estamos haciendo

export function MyOrder() {
    const {
        cartProducts,
        setCartProducts,
    } = useContext(ShoppingContext)

    const groupedProducts = [] 

    cartProducts.map(product => {
        const existingProduct = groupedProducts.find(pro => pro.title === product.title)

        if (existingProduct) {
            existingProduct.quantity += 1
        } else {
            groupedProducts.push({ ...product, quantity: 1 })
        }
    })

    const lessProduct = (product) => {
        let newProducts = [...cartProducts]
        let index = newProducts.findIndex(pro => pro.title === product.title)
        newProducts.splice(index, 1)
        setCartProducts(newProducts)
    }

    const plusProduct = (product) => {
        let newProducts = [...cartProducts]
        let index = newProducts.findIndex(pro => pro.title === product.title)
        let newProduct = newProducts.find(pro => pro.title === product.title)
        newProducts.splice(index, 0, newProduct)
        setCartProducts(newProducts)
    }

    const deleteProduct = (product) => {
        const newProducts = cartProducts.filter(pro => pro.title !== product.title)
        setCartProducts(newProducts)
    }

Yo lo hice de otra forma y estoy satisfecho con ella:

const {cartProducts, setCartProducts, setCounter} = useContext(Context)

    const deleteItemsFromCart = (id)=>{
        const newCart = [...cartProducts];
        const itemIndex = newCart.findIndex(item => item.id === id);
        newCart.splice(itemIndex, 1);
        setCartProducts(newCart)
        setCounter(newCart.length)
    }