Search code examples
javascriptjsonreactjscommerce

Having trouble displaying the total price in Cart


So the problem I am currently facing is this. I have a Cart logic located in the CartContext. Everything works except subtotal it should display the price total price of the items, but it is displaying NAN. Here is the REAL link to the CodeSandbox for a better understanding https://codesandbox.io/s/bold-shockley-rmihl Cart Context

import React from "react";
function getCartFromLocalStorage() {
  return localStorage.getItem("cart")
    ? JSON.parse(localStorage.getItem("cart"))
    : [];
}

const CartContext = React.createContext();

function CartProvider({ children }) {
  const [cart, setCart] = React.useState(getCartFromLocalStorage());
  const [total, setTotal] = React.useState(0);
  const [cartItems, setCartItems] = React.useState(0);

  React.useEffect(() => {
    localStorage.setItem("cart", JSON.stringify(cart));

    let newTotal = cart.reduce((total, cartItem) => {
      return (total += cartItem.amount * cartItem.price);
    }, 0);
    newTotal = parseFloat(newTotal.toFixed(2));
    setTotal(newTotal);
    // cart items
    let newCartItems = cart.reduce((total, cartItem) => {
      return (total += cartItem.amount);
    }, 0);
    setCartItems(newCartItems);
  }, [cart]);

  // global functions
  const removeItem = id => {
    setCart([...cart].filter(item => item.id !== id));
  };
  const increaseAmount = id => {
    const newCart = [...cart].map(item => {
      return item.id === id
        ? { ...item, amount: item.amount + 1 }
        : { ...item };
    });
    setCart(newCart);
  };
  const decreaseAmount = (id, amount) => {
    if (amount === 1) {
      removeItem(id);
      return;
    } else {
      const newCart = [...cart].map(item => {
        return item.id === id
          ? { ...item, amount: item.amount - 1 }
          : { ...item };
      });

      setCart(newCart);
    }
  };
  const addToCart = book => {
    const { id, image, by, bookName,RegularPrice } = book;
    const item = [...cart].find(item => item.id === id);

    if (item) {
      increaseAmount(id);
      return;
    } else {
      const newItem = { id, image, by, bookName, RegularPrice, amount: 1 };
      const newCart = [...cart, newItem];
      setCart(newCart);
    }
  };
  const clearCart = () => {
    setCart([]);
  };
  return (
    <CartContext.Provider
      value={{
        cart,
        cartItems,
        total,
        removeItem,
        increaseAmount,
        decreaseAmount,
        addToCart,
        clearCart
      }}
    >
      {children}
    </CartContext.Provider>
  );
}

export { CartContext, CartProvider };

Cart Item

import React, { useContext } from "react";
import {Link, useHistory } from 'react-router-dom'
import { CartContext } from "../../context/cart";
import { FaAngleDown, FaAngleUp } from "react-icons/fa";
import Checkout from "./Checkout";
export default function CartItem({ id, image,bookName, RegularPrice, by, amount }) {
  const { removeItem, increaseAmount, decreaseAmount } = React.useContext(
    CartContext
  );
  return (
      <div id={id} className="cart__item">
          <img className='cart__image' src={image}  />
        <div className='cart__itemdesc'>
         <h4>{bookName}</h4>
        <h6 className='cart__by'>By: {by}</h6>
        <button
          className="cart__removebtn"
          onClick={() => {
            removeItem(id);
          }}
         >
          Remove
        </button>
        <div>
        <button
          className="cart-btn amount-btn"
          onClick={() => {
            increaseAmount(id);
          }}
        >
          <FaAngleUp />
        </button>
        <p className="item-amount">{amount}</p>
        <button
          className="cart-btn amount-btn"
          onClick={() => {
            decreaseAmount(id, amount);
          }}
        >
          <FaAngleDown />
        </button>
      </div>
        </div>  
        <span className='circle'><span className='circleone'></span></span>
        <span className='cart__regular'>{RegularPrice}</span>      
        <div>   
        <Checkout />
        </div>    
    </div>
  );
}

Checkout

import React,{useContext} from 'react'
import { CartContext } from '../../context/cart'
import {Link, useHistory } from 'react-router-dom'
import EmptyCart from './EmptyCart';

const Checkout = () => {
  const history = useHistory()
  const {cart, total} = useContext(CartContext)
  if (cart.length === 0) {
    return <EmptyCart />;
  }

    return (
        <div className='checkout'>
            <h2>Summary</h2>
            <h2>Subtotal : ${total}</h2>
            <Link to='/stripecontainer' className='checkout__btnOne'>Proceed to Checkout</Link>            
        </div>
    )
}

export default Checkout

Solution

  • Your problem is in the newTotal calculation function, cartItem holds RegularPrice property and not price property

    change this:

    let newTotal = cart.reduce((total, cartItem) => {
          return (total += cartItem.amount * cartItem.price);
    

    to this:

    let newTotal = cart.reduce((total, cartItem) => {
          return (total += cartItem.amount * cartItem.RegularPrice);
    

    cart item property's:

    CartItem({
      id,
      image,
      bookName,
      RegularPrice,
      by,
      amount
    })
    

    working sandbox: https://codesandbox.io/s/eloquent-albattani-ojx20?file=/src/CartContext.js