Home > Software design >  The react-use-cart needs the string ( id ) but my api data only generates the object ( _id ), how ca
The react-use-cart needs the string ( id ) but my api data only generates the object ( _id ), how ca

Time:01-28

I'm creating a cart and I need to add the item, the function has the id of the item as a requirement, but my item only generates the _id and not just the id. The problem to be simple for those who have a lot of knowledge, thanks in advance to the collaborators

Error

Index.js ( Product details )

import React, { useState, useEffect } from "react";
import { useParams } from "react-router";
import Popup from "reactjs-popup";
import "reactjs-popup/dist/index.css";
import { ThreeDots } from "react-loader-spinner";
import { useCart } from "react-use-cart";

//Local

import Nav from "../../components/Nav";
import api from "../../../services/api";
import Best from "../Best/index";
import { TitleCaurosel } from "../style";

//Icons / Images

import { AiFillStar } from "react-icons/ai";
import { BsArrowLeft, BsArrowRight } from "react-icons/bs";

//Style

import {
  Product,
  Images,
  Main,
  Other,
  Details,
  Title,
  Description,
  Stars,
  Colors,
  Color,
  ColorSelected,
  Price,
  Cart,
} from "./style";

const Index = () => {
  const params = useParams();
  const { addItem } = useCart();

  const [data, setData] = useState(undefined);
  const [error, setError] = useState(undefined);
  const [color, setColor] = useState(undefined);
  const [nameColor, setNameColor] = useState(undefined);
  const [index, setIndex] = useState(0);
  const [popup, setPopup] = useState(false);
  const [current, setCurrent] = useState(0);
  const [main, setMain] = useState(undefined);

  const ref = React.createRef();
  const { height, width } = useWindowDimensions();

  function getWindowDimensions() {
    const { innerWidth: width, innerHeight: height } = window;
    return {
      width,
      height,
    };
  }

  function useWindowDimensions() {
    const [windowDimensions, setWindowDimensions] = useState(
      getWindowDimensions()
    );

    useEffect(() => {
      function handleResize() {
        setWindowDimensions(getWindowDimensions());
      }

      window.addEventListener("resize", handleResize);
      return () => window.removeEventListener("resize", handleResize);
    }, []);

    return windowDimensions;
  }

  const config = {
    headers: {
      "Content-type": "application/json",
      Authorization: `Bearer ${localStorage.getItem("token")}`,
    },
  };

  useEffect(() => {
    api.get(`/items/${params.id}`).then((response) => setData(response.data));
  }, []);

  const addToCart = () => {
    if (color !== undefined) {
      api
        .post(
          `/cart`,
          {
            itemId: params.id,
            quantity: 1,
            colors: data.images,
            colorSelected: color,
            img: data.images[0].src,
          },
          config
        )
        .then((response) => {
          if (response.status === 200 || response.status === 201) {
            window.location.pathname = "/Cart";
          }
        });
    } else {
      setError(1);
    }
  };

  const numberFormat = (value) =>
    new Intl.NumberFormat("pt-br", {
      style: "currency",
      currency: "BRL",
    }).format(value);

  const handleTab = (index) => {
    setMain(undefined);
    setIndex(index);

    if (color !== undefined && nameColor !== undefined) {
      setColor(undefined);
      setNameColor(undefined);
    }
  };

  const nextSlide = () => {
    setCurrent(current === data.images.length - 1 ? 0 : current   1);
  };

  const prevSlide = () => {
    setCurrent(current === 0 ? data.images.length - 1 : current - 1);
  };

  useEffect(() => {
    if (data !== undefined) {
      if (!Array.isArray(data.images) || data.images.length <= 0) {
        return null;
      }
    }
  });

  const changeColor = (id, name) => {
    setColor(id);
    setNameColor(name);
    setError(undefined);

    const filter = data.images.filter((item) => item._id === id);
    setMain(filter[0].src);
  };

  return data !== undefined ? (
    <div>
      {/*Popup*/}

      {popup === true && (
        <Popup
          open={true}
          position="center center"
          onClose={() => setPopup(false)}
        >
          <section className="slider">
            <BsArrowLeft className="left-arrow" onClick={prevSlide} />
            <BsArrowRight className="right-arrow" onClick={nextSlide} />
            {data.images.map((slide, index) => {
              return (
                <div
                  className={index === current ? "slide active" : "slide"}
                  key={index}
                >
                  {index === current && (
                    <div
                      style={{
                        width: width / 2,
                        height: height / 2,
                        backgroundImage: `url(${slide.src})`,
                        backgroundRepeat: "no-repeat",
                        backgroundSize: "contain",
                        backgroundPosition: "center",
                      }}
                    />
                  )}
                </div>
              );
            })}
          </section>
        </Popup>
      )}

      <Nav />

      <div
        style={{
          height: "90vh",
          display: "grid",
          justifyContent: "center",
          alignItems: "center",
          gridTemplateColumns: "85%",
          gridTemplateRows: "100%",
          gridColumnGap: "5px",
        }}
      >
        <Product key={data._id}>
          <Images>
            <div
              style={{
                display: "grid",
                marginRight: "3%",
                height: height / 1.3,
              }}
              ref={ref}
            >
              <Other
                style={{
                  width: width / 10,
                  backgroundImage: `url(${data.images[0].src})`,
                  backgroundPosition: "center",
                  backgroundRepeat: "no-repeat",
                  backgroundSize: "60%",
                }}
                alt={`Image de ${data.name}`}
                key={0}
                onClick={() => handleTab(0)}
              />
              {data.images[1] !== undefined && (
                <Other
                  style={{
                    marginTop: "5%",
                    width: width / 10,
                    backgroundImage: `url(${data.images[1].src})`,
                    backgroundPosition: "center",
                    backgroundRepeat: "no-repeat",
                    backgroundSize: "60%",
                  }}
                  alt={`Image de ${data.images[1].name}`}
                  key={1}
                  onClick={() => handleTab(1)}
                />
              )}

              {data.images[2] !== undefined && (
                <Other
                  style={{
                    marginTop: "5%",
                    width: width / 10,
                    backgroundImage: `url(${data.images[2].src})`,
                    backgroundPosition: "center",
                    backgroundRepeat: "no-repeat",
                    backgroundSize: "60%",
                  }}
                  alt={`Image de ${data.name}`}
                  key={2}
                  onClick={() => handleTab(2)}
                />
              )}

              {data.images[3] !== undefined && (
                <Other
                  style={{
                    marginTop: "5%",
                    width: width / 10,
                    backgroundImage: `url(${data.images[3].src})`,
                    backgroundPosition: "center",
                    backgroundRepeat: "no-repeat",
                    backgroundSize: "60%",
                  }}
                  alt={`Image de ${data.name}`}
                  key={1}
                  onClick={() => handleTab(3)}
                />
              )}

              {data.images[4] !== undefined && (
                <div>
                  {data.images.length < 5 ? (
                    <Other
                      style={{
                        width: width / 10,
                        backgroundImage: `url(${data.images[3].src})`,
                        backgroundPosition: "center",
                        backgroundRepeat: "no-repeat",
                        backgroundSize: "60%",
                      }}
                      alt={`Image de ${data.name}`}
                      key={2}
                      onClick={() => handleTab(3)}
                    />
                  ) : (
                    <Other
                      style={{
                        width: width / 10,
                      }}
                      onClick={() => setPopup(true)}
                      alt={`Image de ${data.name}`}
                    >
                      <p>  5</p>
                    </Other>
                  )}
                </div>
              )}
            </div>
            <div
              style={{
                backgroundColor: "#F6F6F6",
                display: "flex",
                justifyContent: "center",
                alignItems: "center",
              }}
            >
              <Main
                style={{
                  backgroundImage: `url(${
                    main === undefined ? data.images[index].src : main
                  })`,
                  backgroundPosition: "center",
                  backgroundRepeat: "no-repeat",
                  backgroundSize: "80%",
                  width: width / 2.8,
                  height: height / 1.5,
                }}
              />
            </div>
          </Images>

          <Details>
            <Title>{data.name}</Title>
            <Description>{data.description}</Description>
            <Stars>
              <AiFillStar />
              <AiFillStar />
              <AiFillStar />
              <AiFillStar />
              <AiFillStar />
              <p>441 Avaliações</p>
            </Stars>
            <Colors>
              {error === undefined && color === undefined && (
                <p style={{ color: "#000" }}>Selecione uma cor:</p>
              )}
              {error === 1 && color === undefined && (
                <p style={{ color: "#ff0000" }}>
                  Selecione uma cor: (Obrigatório)
                </p>
              )}
              {error === undefined &&
                color !== undefined &&
                nameColor !== undefined && (
                  <p style={{ color: "#000" }}>Cor selecionada: {nameColor}</p>
                )}
              <div
                style={{
                  display: "flex",
                  marginTop: "1%",
                  width: "100%",
                  flexWrap: "wrap",
                  alignItems: "center",
                }}
              >
                {data.images.map((item) =>
                  color === item._id ? (
                    <ColorSelected onClick={() => setColor(undefined)}>
                      <div style={{ backgroundColor: item.color }} />
                    </ColorSelected>
                  ) : (
                    <Color
                      style={{ backgroundColor: item.color }}
                      onClick={() => {
                        changeColor(item._id, item.name);
                      }}
                    />
                  )
                )}
              </div>
            </Colors>
            <Price>{numberFormat(data.price)}</Price>
            {console.log(data)}
            <Cart onClick={() => addItem(data)}>
              Adicionar ao carrinho
            </Cart>
          </Details>
        </Product>
      </div>

      <div style={{ paddingLeft: "130px" }}>
        <TitleCaurosel>Você pode gostar!</TitleCaurosel>
        <Best />
      </div>
    </div>
  ) : (
    <div
      style={{
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
        width: width,
        height: height,
      }}
    >
      <ThreeDots
        height="300"
        width="300"
        radius="9"
        color="#8c6d55"
        ariaLabel="three-dots-loading"
        wrapperStyle={{}}
        wrapperClassName=""
        visible={true}
      />
    </div>
  );
};

export default Index;


Cart.js

import React, { useState, useEffect } from "react";
import Nav from "../components/Nav";
import Select from "react-select";
import api from "../../services/api";
import { ThreeDots } from "react-loader-spinner";
import { useCart } from "react-use-cart";

//Icons

import { BiTrash } from "react-icons/bi";
import { MdOutlineEditLocationAlt } from "react-icons/md";
import { HiOutlineShoppingBag } from "react-icons/hi";

//Style

import {
  Container,
  Box1,
  Box2,
  Box3,
  Title,
  Product,
  Image,
  Name,
  Price,
  Border,
  Stock,
  PriceTotal,
  Delete,
  Cupom,
  BorderTraced,
  Subtotal,
  Items,
  Total,
  Checkout,
  NextToBuy,
  Empty,
} from "./style";

const Index = () => {
  function getWindowDimensions() {
    const { innerWidth: width, innerHeight: height } = window;
    return {
      width,
      height,
    };
  }

  function useWindowDimensions() {
    const [windowDimensions, setWindowDimensions] = useState(
      getWindowDimensions()
    );

    useEffect(() => {
      function handleResize() {
        setWindowDimensions(getWindowDimensions());
      }

      window.addEventListener("resize", handleResize);
      return () => window.removeEventListener("resize", handleResize);
    }, []);

    return windowDimensions;
  }

  const { height, width } = useWindowDimensions();

  const {
    isEmpty,
    items,
    cartTotal,
    updateItemQuantity,
    removeItem,
    emptyCart,
  } = useCart();

  return (
    <Container>
      {isEmpty ? (
        <Empty>
          <Nav />

          <div
            style={{
              display: "flex",
              justifyContent: "center",
              alignItems: "center",
              textAlign: "center",
              height: "80vh",
            }}
          >
            <div>
              <HiOutlineShoppingBag className="icon-empty" />
              <h1>Sua sacola está vazia</h1>
              <p className="text-empty">
                Parece que você não adicionou nada a sua sacola. <br /> Vá em
                frente e explore as principais categorias.
              </p>
              <div
                style={{
                  display: "flex",
                  justifyContent: "center",
                  alignItems: "center",
                  textAlign: "center",
                }}
              >
                <a className="button" href="/#Produtos">
                  Explorar produtos
                </a>
              </div>
            </div>
          </div>
        </Empty>
      ) : (
        <Container>
          <Nav />

          <div
            style={{
              display: "flex",
              justifyContent: "center",
              height: height,
              marginTop: "3%",
              marginBottom: "10%",
            }}
          >
            <Box1 style={{ width: width / 2.8, height: height }}>
              <Title>Seus items</Title>
            </Box1>
            <div>
              <Box2 style={{ width: width / 4, height: height / 5 }}>
                <Title>Frete</Title>
                <p className="title">Endereço:</p>
                <span></span>
                <span></span>
                <p className="title">Estimativa de entrega:</p>
                <span>30/12/2022</span>

                <MdOutlineEditLocationAlt />
              </Box2>
              <Box3 style={{ width: width / 4, height: height / 1.4 }}>
                <Cupom>
                  <input placeholder="Cupom de desconto" />
                  <button>Aplicar</button>
                </Cupom>

                <BorderTraced />

                <Subtotal>
                  <p>Subtotal</p>
                  <p></p>
                </Subtotal>

                <Items>
                  <div>
                    <p>Frete</p>
                    <p>R$ 399,99</p>
                  </div>
                </Items>

                <BorderTraced />

                <Total>
                  <p>Total</p>
                  <p></p>
                </Total>

                <Checkout>Finalizar compra</Checkout>
                <NextToBuy
                  onClick={() => {
                    window.location.pathname = "/Products";
                  }}
                >
                  Continuar comprando
                </NextToBuy>
              </Box3>
            </div>
          </div>
        </Container>
      )}
    </Container>
  );
};

export default Index;

Index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import Routes from './routes';
import { CartProvider } from 'react-use-cart';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <CartProvider>
      <Routes />
    </CartProvider>
  </React.StrictMode>
);

CodePudding user response:

Not sure if this is the best/most efficient approach, but you could always create an Item object with the attributes required for the addItem() method. Then map the required data from your data object to the new item object, and instead of using addItem(data) you could use addItem(item).

CodePudding user response:

Add the property when setting the value:

useEffect(() => {
  api.get(`/items/${params.id}`)
    .then(({ data }) => {
        setData({
            ...data,
            id: data._id
        });
    });
}, []);
  • Related