Nazareno Garma
Nazareno Garma

Reputation: 23

How can I calculate the total price of my array by calculating my property price by quantity?

I am needing to return the total price of each product with reference to the quantity that has been added to the cart, with a single product it works fine, but when adding another product it adds the value as if it were a string and not the multiplication in total

[CartContext.js]

import React, { createContext, useState } from "react";

export const CarritoContext = createContext();

export default function CartContext({ children }) {
  const [addToCarrito, setAddToCarrito] = useState([]);
  const [productoRecibe] = useState({});

  function addItem(item, quantity) {
    const foundProdIndex = addToCarrito.findIndex(
      (product) => product.item.id === item.id
    );
    if (foundProdIndex === -1) {
      setAddToCarrito([...addToCarrito, { item, quantity }]);
    } else {
      const newProducts = [...addToCarrito];
      newProducts[foundProdIndex].quantity += quantity;
      setAddToCarrito(newProducts);
    }

    if (quantity === 0) {
      setAddToCarrito([...addToCarrito]);
    }
  }

  console.log(addToCarrito);

  function clear() {
    setAddToCarrito([]);
  }

  function removeItem(itemId) {
    const newItems = addToCarrito.filter((item) => item.item.id !== itemId);
    setAddToCarrito(newItems);
  }

  return (
    <>
      <CarritoContext.Provider
        value={{
          addToCarrito,
          setAddToCarrito,
          clear,
          addItem,
          removeItem,
          productoRecibe,
        }}
      >
        {children}
      </CarritoContext.Provider>
    </>
  );
}

[Cart.js] [HERE IS THE PROBLEM IN THE H1 OF THE SECOND FOOTER]

import React, { useContext, useState } from "react";
import { Link } from "react-router-dom";
import { CarritoContext } from "../../context/CartContext";
import "./Cart.scss";
import { BsTrash } from "react-icons/bs";

const Cart = () => {
  let { addToCarrito } = useContext(CarritoContext);
  let { setAddToCarrito } = useContext(CarritoContext);
  let { clear } = useContext(CarritoContext);
  let { addItem } = useContext(CarritoContext);
  let { removeItem } = useContext(CarritoContext);

  console.log(addToCarrito);

  return (
    <>
      {addToCarrito.map((producto) => {
        return (
          <div>
            <div className="container">
              <section id="cart">
                <article className="product">
                  <header>
                    <img
                      src={producto.item.imageUrl}
                      alt=""
                      style={{
                        backgroundColor: "white",
                        width: "100%",
                        height: "100%",
                        objectFit: "contain",
                      }}
                    />
                  </header>

                  <div className="content">
                    <h1>
                      {producto.item.name}{" "}
                      <BsTrash
                        onClick={() => removeItem(producto.item.id)}
                        className="basurita"
                      />
                    </h1>
                    {producto.item.category} | {producto.item.brand} |{" "}
                    {producto.item.color}
                  </div>

                  <footer className="content">
                    <span className="qt">
                      <strong>Qty:</strong> {producto.quantity}
                    </span>

                    <h2 className="full-price">${producto.item.price}</h2>
                  </footer>
                </article>
              </section>
            </div>
          </div>
        );
      })}

      <footer id="site-footer">
        <div className="container clearfix">
          <div className="right">

            <h1 className="total">
              Total: <span>${addToCarrito.map((product) => {
                return product.item.price * product.quantity  
              })} </span>
            </h1>
            <Link to={'/checkout'} className="btn">Checkout</Link>
          </div>
        </div>
      </footer>
    </>
  );
};

export default Cart;

Upvotes: 0

Views: 773

Answers (1)

Robin Zigmond
Robin Zigmond

Reputation: 18249

The problem is that you are trying to put an array of numbers into the heading, here:

Total: <span>${addToCarrito.map((product) => {
  return product.item.price * product.quantity  
})} </span>

In rendering this, React will convert it to a string - and Javascript by default will stringify arrays by separating them with commas, which is why you're seeing a comma-separated string when you have more than one product.

Rendering an array directly doesn't make much sense. You say you want the total price, so you need to sum that array - which you can do with reduce:

Total: <span>${addToCarrito.map((product) => {
  return product.item.price * product.quantity  
}).reduce((a, b) => a + b, 0)} </span>

Although as a stylistic point, I don't particularly like putting such a complex expression inside {...} to render, so I'd probably define this as a constant outside the return value, so you can just render Total: <span>${totalPrice}<span> or something like that. But I leave that decision up to you.

Upvotes: 2

Related Questions