0

I have a function that calls 2 functions, one uploads an image and stores it in some directory, and the other send product related data to edit/store in the database:

  const uploadImage = async () => {
    let formData = new FormData();
    formData.append("image", product.image);

    const res = await fetch("http://localhost:8000/api/upload", {
      method: "POST",
      body: formData,
    });
    const data = await res.json();
    setProduct({...product,path: data.data.path});
  };

  const saveProduct = async () => {

    if (product.id) {
      await fetch("http://localhost:8000/api/edit-product", {
        method: "PUT",
        body: JSON.stringify(product),
        headers: { "Content-Type": "application/json" },
      });

    } else {
      fetch("http://localhost:8000/api/new-product", {
        method: "POST",
        body: JSON.stringify(product),
        headers: { "Content-Type": "application/json" },
      })
    }

  };

  const saveProductMain = () => {
    uploadImage();
    saveProduct();

  };

when saveProductMain is called, it will call uploadImage which gets a response for the uploaded image path, and then sets the state product.path, now i want to send that path to /new-product so i can recieve the path in the route method and then store it in the database, but when i console.log the state product.path in saveProduct function, it will return the value only the second time the function is called, the first time it returns null, so product.path is null when its sent in the fetch body, how can i solve that issue ?

1
  • That is by design, setting state variable does not update the variable itself in current context, the value will be updated on next render only. Quickfix - make uploadImage function to return some data that is needed in your other function, and pass this data as an argument for this function. Another approach - utilize useRef hook. Commented Apr 22, 2024 at 15:22

1 Answer 1

0

State updates don't take effect until the next render, this is why it only works on the second time. product in state can never be updated by the time you call the second function.

One simple alternative is to have the first function return the product and use that value directly in the second. You may be able to remove product from state altogether, but if you still need it in state you can leave it.

Example:

  const uploadImage = async () => {
    let formData = new FormData();
    formData.append("image", product.image);

    const res = await fetch("http://localhost:8000/api/upload", {
      method: "POST",
      body: formData,
    });
    const data = await res.json();

    // You may be able to delete this line if not needed elseware in your code.
    setProduct({...product,path: data.data.path});

    return {...product,path: data.data.path};
  };

  const saveProduct = async (product) => {

    if (product.id) {
      await fetch("http://localhost:8000/api/edit-product", {
        method: "PUT",
        body: JSON.stringify(product),
        headers: { "Content-Type": "application/json" },
      });

    } else {
      fetch("http://localhost:8000/api/new-product", {
        method: "POST",
        body: JSON.stringify(product),
        headers: { "Content-Type": "application/json" },
      })
    }

  };

  const saveProductMain = async () => {
    const product = await uploadImage();
    saveProduct(product);
  };

Since uploadImage is async, you will need to make your save function async as well so that you can await the uploadImage call.

Sign up to request clarification or add additional context in comments.

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.