0

for learning purposes I'm trying to create an eshop, but I'm facing issues when adding a product to the cart page. Product's 'id' is undefined in the cart. Products are fetched from my MongoDB database.

Routes component:

  const PageRoutes = () => (
  <Routes>
     <Route path="/" element={<MainLayout />}>
     <Route index element={<HomePage />} />
     <Route path="/about-us" element={<AboutUs />} />
     <Route path="/product-catalog" element={<ProductCatalog />} />
     <Route path="/order" element={<OrderPage />} />
     <Route path="/product/:id" element={<ProductInformation />} />

     <Route path="auth/" element={<AuthLayout />}>
       <Route path="login" element={<LoginPage />} />
       <Route path="register" element={<RegisterPage />} />
     </Route>

     <Route path="/cart" element={<CartPage />} />
   </Route>
 </Routes>
);

Service file which fetches products:

const domain = 'http://localhost:8000';
const databaseCollection = 'api/products';
const relationsParams = 'joinBy=categoryId&joinBy=woodTypeId';

const fetchProducts = async () => {
  const response = await fetch(`${domain}/${databaseCollection}/?${relationsParams}`);
  const products = await response.json();

  return products;
};

const fetchProductById = async (id) => {
  const response = await fetch(`${domain}/${databaseCollection}/${id}?${relationsParams}`);
  const product = await response.json();

  console.log('fetchProductById', id); // it prints the id correctly, not as undefined

  return product;
};

const ProductService = {
  fetchProducts,
  fetchProductById,
};

export default ProductService;

Cart component where I face the issue:

import * as React from 'react';
import { Container } from '@mui/material';
import { useParams } from 'react-router-dom';
import ProductService from '../../services/product-service';

const CartPage = () => {
const { id } = useParams();
const [productsInCart, setProductsInCart] = React.useState([]);

console.log('id from useParams', id);

React.useEffect(() => {
  (async () => {
    const fetchedProduct = await ProductService.fetchProductById(id);
    setProductsInCart(fetchedProduct);
  })();
}, [id]);

return (
  <Container>
    <pre>
      {JSON.stringify(productsInCart, null, 4)}
    </pre>
  </Container>
 );
};

export default CartPage;

Button which should add the product to the cart from ProductInformation component (it also logs the id in the console correctly):

<CustomButton
  onClick={() => {
    navigate('/cart');
    addToCart({ id });
    console.log(`add to cart ${id}`);
  }}
>
  Add to cart
</CustomButton>

Error that I can see in server's terminal when it breaks:

GET /api/products/632db73759073e4cb274e011?joinBy=categoryId&joinBy=woodTypeId 200 1178 - 
336.686 ms
stringValue: '"undefined"',
kind: 'ObjectId',
value: 'undefined',
path: '_id',
reason: BSONTypeError: Argument passed in must be a string of 12 bytes or a string of 24 hex 
characters or an integer

View model for the product:

const categoryViewModel = require('./category-view-model');
const woodTypeViewModel = require('./wood-type-view-model');

const productEverythingPopulatedViewModel = (productDocument) => ({
  id: productDocument._id.toString(),
  title: productDocument.title,
  description: productDocument.description,
  category: categoryViewModel(productDocument.categoryId),
  price: productDocument.price,
  img: productDocument.img,
  woodType: woodTypeViewModel(productDocument.woodTypeId),
  createdAt: productDocument.createdAt,
  updatedAt: productDocument.updatedAt,
})

module.exports = productEverythingPopulatedViewModel;

Can anyone see the mistake I made?

Thanks!

kkkjjj
  • 73
  • 7

1 Answers1

0

You should add the param to the route like you did in product route.

<Route path="/cart/:id" element={<CartPage />} />

And then add the id to the navigate url.

<CustomButton   onClick={() => {
    navigate(`/cart/${id}`);
    addToCart({ id });
    console.log(`add to cart ${id}`);   }}
>   Add to cart </CustomButton>
  • ah yes, that worked, thanks! Will have to figure out how to save it in the cart now, as now it only shows the one that was added recently and changes if you add another one.. – kkkjjj Oct 07 '22 at 12:42