0

Using react/redux toolkit

I have an item creation screen which uploads an image of the item and then creates an entry in my database for that item.

One of the database values is the imageURL, which should point to the recently uploaded image.

I have a stateful value for the imageURL and this should be changed to the correct path after the file has been uploaded but before dispatch of the creation of the database entry, but I can't get the imageURL to be set before the dispatch occurs.

I've tried useEffect as well as async but it imageURL seems to only be set after dispatch.

const [imageURL, setImageURL] = useState('');

  //File upload handler
  const uploadFileHandler = async (file) => {
    const formData = new FormData();
    formData.append('image', file);
    setUploading(true);
    try {
      const config = {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      };
      const fileURL = await axios.post('/api/upload', formData, config);
      setUploading(false);
      return fileURL.data; //this is the path of the uploaded file
    } catch (error) {
      console.error(error);
      setUploading(false);
    }
  };

  //TODO: Submit handler
  const submitHandler = async (e) => {
    e.preventDefault();
    let path = await uploadFileHandler(uploadFile); //this should give me the URL from the upload
    setImageURL(path); //this should set the Image URL to the above value, but does not
    dispatch(createItem(data, headers));
  };

If anyone knows how to fix this I would appreciate it.

Thanks

4
  • What is setImageURL? Is it a useState setter, or a redux action? If it's a redux action, is there any reason you aren't calling dispatch on it? Commented Jun 7, 2021 at 3:05
  • oh sorry that got missed in my copy/paste of the code. it's a setter: const [imageURL, setImageURL] = useState(''); Commented Jun 7, 2021 at 3:08
  • It looks like it should work. What do you mean by "this should set the Image URL to the above value, but does not"? Where do you expect it to see and don't? Commented Jun 7, 2021 at 3:43
  • thanks for your help with this, answered below. Commented Jun 7, 2021 at 4:09

1 Answer 1

1

It will work not because setImageURL and dispatch is on the same function. What happens is it finishes the function first befire setting the Image URL.

What you can do is insert it as a "data" in the dispatch like:

 const submitHandler = async (e) => {
    e.preventDefault();
    let path = await uploadFileHandler(uploadFile);
    dispatch(createItem({
       ...data,
       image_url: path, // idk if this is the correct property name on the data
    }, headers));
  };

Or use useEffect hook:

 const submitHandler = async (e) => {
    e.preventDefault();
    let path = await uploadFileHandler(uploadFile);
    setImageURL(path);
  };

  useEffect(() => {
     if (imageURL !== '') {
        dispatch(createItem(data, headers));
     }
  }, [imageURL]);

This way dispatch will trigger if imageURL changes.

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.