Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Uncaught TypeError: cart.map is not a function redux toolkit

I am receiving an error of Uncaught TypeError: cart.map is not a function

My cartSlice.js page:

import { createSlice } from "@reduxjs/toolkit";

const cartSlice = createSlice({
  name: "cart",
  initialState: {
    cart: [],
  },
  reducers: {
    addToCart: (state, action) => {
      const itemInCart = state.cart.find(
        (item) => item.id === action.payload.id
      );
      if (itemInCart) {
        itemInCart.quantity++;
      } else {
        state.cart.push({ ...action.payload, quantity: 1 });
      }
    },
    incrementQuantity: (state, action) => {
      const item = state.cart.find((item) => item.id === action.payload);
      item.quantity++;
    },
    decrementQuantity: (state, action) => {
      const item = state.cart.find((item) => item.id === action.payload);
      if (item.quantity === 1) {
        item.quantity = 1;
      } else {
        item.quantity--;
      }
    },
    removeItem: (state, action) => {
      const removeItem = state.cart.filter(
        (item) => item.id !== action.payload
      );
      state.cart = removeItem;
    },
  },
});

export const cartReducer = cartSlice.reducer;
export const { addToCart, incrementQuantity, decrementQuantity, removeItem } =
  cartSlice.actions;

My store.js page (where I configure my store):

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import { configureStore, combineReducers } from "@reduxjs/toolkit";

import { cartReducer } from "./cartSlice";
import appApi from "../services/appApi";

import storage from "redux-persist/lib/storage";
import {
  persistReducer,
  FLUSH,
  REHYDRATE,
  PAUSE,
  PERSIST,
  PURGE,
  REGISTER,
} from "redux-persist";

import productReducer from "./productSlice";
import customerReducer from "./customerSlice";
import userReducer from "./userSlice";
import thunk from "redux-thunk";
import packageReducer from "./packageSlice";

const persistConfig = {
  key: "root",
  storage,
  blackList: [appApi.reducerPath],
};

const rootReducer = combineReducers({
  [appApi.reducerPath]: appApi.reducer,
  products: productReducer,
  customers: customerReducer,
  cart: cartReducer,
  user: userReducer,
  packages: packageReducer,
});

const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }).concat(thunk, appApi.middleware),
});

export default store;

My index.js page (where I pass my store in the provider):

import React from "react";
import ReactDOM from "react-dom/client";
import { Provider } from "react-redux";
import store from "./redux/store";
import "./Admin/assets/css/App.css";
import { ChakraProvider } from "@chakra-ui/react";
import theme from "./Admin/theme/theme";
import { ThemeEditorProvider } from "@hypertheme-editor/chakra-ui";
import App from "./App";
import persistStore from "redux-persist/es/persistStore";
import { PersistGate } from "redux-persist/integration/react";

const persistedStore = persistStore(store);

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <ChakraProvider theme={theme}>
    <React.StrictMode>
      <ThemeEditorProvider>
        <Provider store={store}>
          <PersistGate loading={null} persistor={persistedStore}>
            <App />
          </PersistGate>
        </Provider>
      </ThemeEditorProvider>
    </React.StrictMode>
  </ChakraProvider>
);

My Cart.js page:

import Total from "../components/Shop/Total";
import CartItem from "../components/Shop/CartItem";
import { useSelector } from "react-redux";
import { Link, useNavigate } from "react-router-dom";
import Navbar from "../components/Shop/Navbar";
import Footer from "../components/Home/Footer";

function Cart() {
  const cart = useSelector((state) => state.cart);
  console.log(cart);
  const user = useSelector((state) => state.user);
  const navigate = useNavigate();

  return (
    <>
      <div className="mb-5">
        <Navbar />
      </div>
      <div className="cart">
        <div className="cart__left">
          <div>
            <h3>Shopping Cart</h3>
            {cart?.map((item) => (
              <CartItem
                key={item.id}
                id={item.id}
                name={item.name}
                price={item.price}
                quantity={item.quantity}
              />
            ))}
          </div>
        </div>

        <div className="cart__right">
          <Total />
          {user ? (
            <Link to="/checkout">
              <button
                className="btn btn-warning check-btn"
                style={{ width: "20rem", padding: 10 }}
              >
                Procceed To Checkout <i class="bi bi-wallet2"></i>
              </button>
            </Link>
          ) : (
            <Link to="/login">
              <button
                className="btn btn-warning check-btn"
                style={{ width: "20rem", padding: 10 }}
                onClick={() => navigate("/login")}
              >
                LogIn To Checkout <i class="bi bi-wallet2"></i>
              </button>
            </Link>
          )}
        </div>
      </div>
    </>
  );
}

export default Cart;

My CartItem.js page:

import {
  incrementQuantity,
  decrementQuantity,
  removeItem,
} from "../../redux/cartSlice";
import { useDispatch } from "react-redux";

function CartItem({ id, name, price, quantity = 0 }) {
  const dispatch = useDispatch();

  return (
    <div className="cartItem">
      <div className="cartItem__info">
        <p className="cartItem__title">{name}</p>
        <p className="cartItem__price">
          <small>R</small>
          <strong>{price}</strong>
        </p>
        <div className="cartItem__incrDec">
          <button onClick={() => dispatch(decrementQuantity(id))}>-</button>
          <p>{quantity}</p>
          <button onClick={() => dispatch(incrementQuantity(id))}>+</button>
        </div>
        <button
          className="cartItem__removeButton"
          onClick={() => dispatch(removeItem(id))}
        >
          Remove
        </button>
      </div>
    </div>
  );
}

export default CartItem;

My Total.js page:

import { useSelector } from "react-redux";

function Total() {
  const cart = useSelector((state) => state.cart);

  const getTotal = () => {
    let totalQuantity = 0;
    let totalPrice = 0;
    cart?.forEach((item) => {
      totalQuantity += item.quantity;
      totalPrice += item.price * item.quantity;
    });
    return { totalPrice, totalQuantity };
  };

  return (
    <div className="total">
      <h2 className="font-semibold fs-2">ORDER SUMMARY</h2>
      <div>
        <p className="total__p font-medium fs-5">
          total ({getTotal().totalQuantity} products) :{" "}
          <strong>R{getTotal().totalPrice}</strong>
        </p>
      </div>
    </div>
  );
}

export default Total;

I went to my shop page to try and add a product to my cart.

Shop.js page:

import React from "react";
import { motion } from "framer-motion";

import Navbar from "../components/Home/Navbar";
import Hero from "../components/Shop/Hero";
import ShopCard from "../components/Shop/ShopCard";

import { useNavigate } from "react-router-dom";
import { useSelector } from "react-redux";

const Shop = () => {
  const products = useSelector((store) => store.products);
  const navigate = useNavigate();
  const ProductShop = () => (
    <div className="shopping-cart" onClick={() => navigate("/cart")}>
      <div className="bg-white">
        {products?.map((product) => (
          <div key={product.id}>
            <ShopCard
              name={product.name}
              price={product.price}
              desc={product.desc}
            />
          </div>
        ))}
      </div>
    </div>
  );

  return (
    <motion.div
      id="main"
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0, transition: { duration: 0.4 } }}
    >
      <Navbar />
      <Hero />
      {products?.length ? (
        ProductShop()
      ) : (
        <h1 className="fw-bold text-warning fs-3 text-center mt-3">
          Products not availabe
        </h1>
      )}
    </motion.div>
  );
};

export default Shop;

My ShopCard.js page:

import React from "react";
import { useDispatch } from "react-redux";
import { addToCart } from "../../redux/cartSlice";
import { AiOutlineShoppingCart } from "react-icons/ai";

const ShopCard = ({ id, name, price, desc }) => {
  const dispatch = useDispatch();
  return (
    <>
      <section style={{ backgroundColor: "#eee" }}>
        <div className="text-center container py-5">
          <div className="column">
            <div className="col-lg-4 col-md-12 mb-4">
              <div className="card">
                <div
                  className="bg-image hover-zoom ripple ripple-surface ripple-surface-light"
                  data-mdb-ripple-color="light"
                >
                  <a href="#!">
                    <div className="hover-overlay">
                      <div
                        className="mask"
                        style={{ backgroundColor: "rgba(251, 251, 251, 0.15)" }}
                      ></div>
                    </div>
                  </a>
                </div>
                <div className="card-body">
                  <h5 className="card-title mb-3 fw-bolder fs-3">{name}</h5>
                  <div className="mb-2 fs-5">
                    <h2>{desc}</h2>
                  </div>
                  <h6 className="mb-3 fw-bold fs-4">R{price}</h6>
                  <button
                    className="d-flex m-auto bg-warning text-white font-regular fs-5 align-items-center justify-content-center"
                    style={{ width: "100%", padding: 10 }}
                    type="button"
                    onClick={() => dispatch(addToCart({ id, name, price }))}
                  >
                    <AiOutlineShoppingCart fontSize={23} className="me-2" /> Add
                    to Cart
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </section>
    </>
  );
};

export default ShopCard;

Then consoled log to see if it was working:

 const cart = useSelector((state) => state.cart);
  console.log(cart);

My consoled cart:

Object
cart
: 
Array(1)
0
: 
{name: 'Vegan Ham', price: '56', quantity: 4}
length
: 
1

Its working but its not showing it up in my cart page. I have been trying to fix this problem for days now and I don’t understand why it’s not working.

The error is coming from this piece of code:

           {cart?.map((item) => (
                  <CartItem
                    key={item.id}
                    id={item.id}
                    name={item.name}
                    price={item.price}
                    quantity={item.quantity}
                  />
                ))}

Any help would be appreciated. Thanks

>Solution :

const cart = useSelector((state) => state.xyz.cart);

xyz is the key that you set in the store for the value of cartReducer in your store.

export const store = configureStore({
  reducer: {
    xyz: cartReducer,
  },
})
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading