0

Why does my article state doesnt have the same Parameter like my cart.filter element. What am I doing wrong, using the useState Hook.

  const [article, setArticle] = useState();
  const [cart, setCart] = useState([]);
  const { id } = useParams();
  useEffect(() => {
    const fetchCartAndPrice = async () => {
      const { sess } = await ApiClientShoppingCart.getCart();
      setCart(sess.cart);
    };
    setArticle(cart.filter((e) => e.id === id));
    fetchCartAndPrice();
  }, []);
  return (
    <div>
      {console.log(cart.filter((e) => e.id === id))}
      {console.log(article)}
    </div>
  );
}

3 Answers 3

1

In the moment that you are trying set the articles don't have carts yet. You need wait the cart update creating an exclusive useEffect to cart. Something like this:

const [article, setArticle] = useState();
const [cart, setCart] = useState([]);
const { id } = useParams();

useEffect(() => {
  const fetchCartAndPrice = async () => {
  const { sess } = await ApiClientShoppingCart.getCart();
    setCart(sess.cart);
  };

  fetchCartAndPrice();
}, []);

useEffect(() => {
  setArticle(cart.filter((e) => e.id === id));
}, [cart]);

return (
  <div>
    {console.log(cart.filter((e) => e.id === id))}
    {console.log(article)}
  </div>
);
Sign up to request clarification or add additional context in comments.

Comments

0

When you trigger your function setArticle() the async function which fetch the cart didn't finished yet ... So it can't "filter" the (still empty) cart ...

You need to execute that filter thing after the cart is set :

const [article, setArticle] = useState();
const [cart, setCart] = useState([]);
const { id } = useParams();
useEffect(() => {
  const fetchCartAndPrice = async () => {
    const { sess } = await ApiClientShoppingCart.getCart();
    setCart(sess.cart);
  };
}, []);

useEffect(() => {
  // --> ensure we are not in the "init step"
  if (cart.length) {
    setArticle(cart.filter((e) => e.id === id));

    // Not sur where this one belongs ... :
    fetchCartAndPrice();
  }
}, [cart]);

return (
  <div>
    {console.log(cart.filter((e) => e.id === id))}
    {console.log(article)}
  </div>
);

Another maner to do so is to set the article at the same place of the cart :

useEffect(() => {
  const fetchCartAndPrice = async () => {
    const { sess } = await ApiClientShoppingCart.getCart();
    setCart(sess.cart);
    setArticle(sess.cart.filter((e) => e.id === id));
  };
}, []);

1 Comment

if I use your second option (which I would prefer), the setState after the useEffect ist undefined... I dont understand what I am doing wrong
0

Gabriel Furlan gave a great solution. I would use the async declaration at the top level of the useEffect hook. Ex.

const [article, setArticle] = useState();
const [cart, setCart] = useState([]);
const { id } = useParams();

useEffect(async () => {
  const sess = await ApiClientShoppingCart.getCart();
  setCart(sess.cart);
}, []);

useEffect(() => {
  setArticle(cart.filter((e) => e.id === id));
}, [cart]);

return (
  <div>
    {console.log(cart.filter((e) => e.id === id))}
    {console.log(article)}
  </div>
);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.