I want to bring let Vary of Size and varyOfSize from my ProductScreen to my ShoppingCart Screen in React and Node

I want to bring let Vary of Size and let varyOfSize from my ProductScreen to my ShoppingCart Screen because I want to sum those values with the price of my product in Shopping Cart Screen as I have it in Product Screen

ProductScreen

Shopping Cart Screen

Product Screen

import { Link, useNavigate, useParams } from 'react-router-dom';
import axios from 'axios';
import React, { useState, useEffect, useReducer, useContext } from 'react';
import logger from 'use-reducer-logger';
import { Store } from '../Store';

const reducer = (state, action) => {
  switch (action.type) {
    case 'FETCH_REQUEST':
      return { ...state, loading: true };
    case 'FETCH_SUCCESS':
      return { ...state, product: action.payload, loading: false };
    case 'FETCH_FAIL':
      return { ...state, loading: false, error: action.payload };
    default:
      return state;
  }
};

function ProductScreen() {
  const params = useParams();
  const { _id } = params;
  const [color, setColor] = useState(0);
  const [size, setSize] = useState(0);
  const [quantity, setQuantity] = useState(1);
  const navigate = useNavigate();

  let varyOfColor = parseInt(color);
  let varyOfSize = parseInt(size);
  let varyOfQuantity = parseInt(quantity);
  let priceInFunctionOfColorAndSize = varyOfSize + varyOfColor;

  const [{ loading, error, product }, dispatch] = useReducer(logger(reducer), {
    product: {},
    loading: true,
    error: '',
  });

  useEffect(() => {
    const fetchData = async () => {
      dispatch({ type: 'FETCH_REQUEST' });
      try {
        const result = await axios.get(`/api/products/${_id}`);
        dispatch({ type: 'FETCH_SUCCESS', payload: result.data });
      } catch (err) {
        dispatch({ type: 'FETCH_FAIL', payload: err.message });
      }
    };
    fetchData();
  }, [_id]);

  const { state, dispatch: ctxDispatch } = useContext(Store);
  const { cart } = state;

  const addToCartHandler = async () => {
    
    const existItem = cart.cartItems.find((x) => x.name === product.name && x.selectedColor === product.color[color] && x.selectedSize === product.size[size]);
    const qty = existItem ? existItem.quantity + quantity : quantity;
    const { data } = await axios.get(`/api/products/${product.name}`);
    if (data.stock < qty) {
      window.alert('Sorry, product is out of stock');
      return;
    }
    ctxDispatch({
      type: 'CART_ADD_ITEM',
      payload: { ...product, quantity: qty, selectedColor: product.color[color], selectedSize: product.size[size],varyOfColor,varyOfSize},
    });
    navigate('/cart');
  };
  console.log(console.log('Price In Function Of Color And Size: ', (product.price + priceInFunctionOfColorAndSize) * varyOfQuantity));
  console.log("product.color",product.color)
  return (
    loading ? <div>Loading...</div> : error ? <div>{error}</div> :
      <div>
        <div>
          <div>
            <div>
              <div className="product-report">
                <Link to={`/products/${product.name}`}>
                  <img className="image" src={product.image} alt={product.name} ></img>
                </Link>
                <div className="product-description">
                  <div className="name-product">{product.name}</div>
                  <div className="rating-product">{product.rating}</div>
                  <div className="product-price-variation">
                    <div className="product-price">Price:</div>
                    <div className="variation-price">{"$" + (product.price + priceInFunctionOfColorAndSize) * varyOfQuantity}</div>
                  </div>
                  <div className="product-size-variation">
                    <div className="product-size">Size:</div>
                    <div className="size-variation">
                      <select className="size-select-button" value={size} onChange={(event) => { setSize(event.target.value); }}>
                        {
                          product.size && Array.isArray(product.size) ? (
                            product.size.map((item, i) => (
                              <option key={i} value={i}>
                                {item}
                              </option>
                            ))
                          ) : (
                            <option value="">No sizes available</option>
                          )
                        }
                      </select>
                    </div>
                  </div>
                  <div className="product-color-variation">
                    <div className="color-product">Color:</div>
                    <div className="color-variation">
                      <select className="color-select-button" value={color} onChange={(event) => { setColor(event.target.value); }}>
                        {
                          product.color && Array.isArray(product.color) ? (
                            product.color.map((item, i) => (
                              <option key={i} value={i}>
                                {item}
                              </option>
                            ))
                          ) : (
                            <option value="">No colors available</option>
                          )
                        }
                      </select>
                    </div>
                  </div>
                </div>
                <div className="cart-box">
                  <h1 className="price-cart-box">{"$" + (product.price + priceInFunctionOfColorAndSize) * varyOfQuantity}</h1>
                  <h1 className="stock-cart-box">In Stock</h1>
                  <div className="cart-box-buttons">
                    <select className="quantity-select-button" value={quantity} onChange={(event) => { setQuantity(event.target.value); }}>
                      {
                        product.stock ? (
                          [...Array(product.stock).keys()].map((x) => (
                            <option key={x + 1} value={x + 1}>
                              {x + 1}
                            </option>
                          ))
                        ) : (
                          <option value="">No quantity available</option>
                        )
                      }
                    </select>
                    {product.stock > 0 ? <button className="cart-button" onClick={addToCartHandler}>Add to cart</button> :
                      <div>Out Of Stock</div>}
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
  );
}

export default ProductScreen;

Shopping Cart Screen

import { useContext } from 'react';
import { Store } from '../Store';
import { Link } from 'react-router-dom';
import { Helmet } from 'react-helmet-async';
import MessageBox from '../components/MessageBox';
import ListGroup from 'react-bootstrap/ListGroup';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Button from 'react-bootstrap/Button';
import Card from 'react-bootstrap/Card';

export default function CartScreen() {
  const { state, dispatch: ctxDispatch } = useContext(Store);
  const {
    cart: { cartItems },
  } = state;

  return (
    <div>
      <Helmet>
        <title>Shopping Cart</title>
      </Helmet>
      <h1>Shopping Cart</h1>
      <Row>
        <Col md={8}>
          {cartItems.length === 0 ? (
            <MessageBox>
              Cart is empty. <Link to="/">Go Shopping </Link>
            </MessageBox>
          ) : (
            <ListGroup>
              {cartItems.map((item) => (
                <ListGroup.Item key={item.name + item.selectedColor + item.selectedSize}>
                  <Row className="align-items-center">
                    <Col md={4}>
                      <img
                        src={item.image}
                        alt={item.name}
                        className="img-fluid rounded img-thumbnail"
                      ></img>{' '}
                      <Link to={`/product/${item.name}`}>{item.name}</Link>
                      <div>Color: {item.selectedColor}</div>
                      <div>Size: {item.selectedSize}</div>
                      
                    </Col>
                    <Col md={3}>
                      <Button variant="light" disabled={item.quantity === 1}>
                        <i className="fas fa-minus-circle"></i>
                      </Button>{' '}
                      <span>{item.quantity}</span>{' '}
                      <Button variant="light" disabled={item.quantity === item.stock}>
                        <i className="fas fa-plus-circle"></i>
                      </Button>{' '}
                    </Col>
                    <Col md={3}>${item.price * item.quantity}</Col>
                    <Col md={2}>
                      <Button variant="light">
                        <i className="fas fa-trash"></i>
                      </Button>
                    </Col>
                  </Row>
                </ListGroup.Item>
              ))}
            </ListGroup>
          )}
        </Col>
        <Col md={4}>
          <Card>
            <Card.Body>
              <ListGroup variant="flush">
                <h3>
                  Subtotal({cartItems.reduce((a, c) => a + c.quantity, 0)} items) : $
                  {cartItems.reduce((a, c) => a + c.price * c.quantity, 0)}
                </h3>
              </ListGroup>
              <ListGroup>
                <div className="d-grid">
                  <Button
                    type="button"
                    variant="primary"
                    disabled={cartItems.length === 0}
                  >
                    Proceed to Checkout
                  </Button>
                </div>
              </ListGroup>
            </Card.Body>
          </Card>
        </Col>
      </Row>
    </div>
  );
}

You are definitely going to have to provide us with more details and context than that.

Are you saying the product cost should depend on the size? If so, that is not something I would do dynamically, client side or server side, because that just sounds prone to errors. The price should be in the data for each product variant.

1 Like

This is my data. I am using Node and React.

export default {
    /*image: '/images/T-Shirt.jpg',*/
    products: [
      {
        _id:1,
        name: 'T-Shirt-Hurley',
        rating: 4.8,
        image: '/images/T-Shirt.jpg',
        price: 20,
        size: ["Small","Medium","Large"],
        color: ["Red","Blue","Black","White"],
        quantity:[],
        stock: 10
        },
        {
        _id:2,
        name: 'Jean-Levi',
        rating: 4.2,
        image: '/images/Jean.jpg',
        price: 30,
        size: ["Small","Large"],
        color: ["Blue","Black","White"],
        quantity:[],
        stock: 7
        
        },
        {
        _id:3,   
        name: 'Jacket-Quicksilver',
        rating: 40,
        image: '/images/Jacket.jpg',
        price: 35,
        size: ["Medium","Large"],
        color: ["Blue","Black","White"],
        quantity:[],
        stock: 5
        },
        {
        _id:4,
        name: 'T-Shirt-Adidas',
        rating: 4.8,
        image: '/images/T-Shirt-2.jpg',
        price: 20,
        size: ["Small","Medium"],
        color: ["Red","Black","White"],
        quantity:[],
        stock: 3
        },
        {
        _id:5,
        name: 'Jean-Wrangler',
        rating: 4.2,
        image: '/images/Jean-2.jpg',
        price: 30,
        size: ["Medium"],
        color: ["Blue","White"],
        quantity:[],
        stock: 4
        },
        {
        _id:6,
        name: 'Jacket-Champion',
        rating: 4.5,
        image: '/images/Jacket-2.jpg',
        price: 35,
        size: ["Medium","Large"],
        color: ["Black","White"],
        quantity:[],
        stock: 6
         }
         

        ]
      }

If I set small and black, I get a variation in price. The base price in $20. My Product Screen calculates with no problem.

But when I go to Shopping Cart…

I receive my base price.

In my ProductScreen I use this line to get t

<div className="variation-price">{"$" + (product.price + priceInFunctionOfColorAndSize) * varyOfQuantity}</div>