Skip to content

‘await’ call doesn’t wait

My app is trying to upload files to S3. S3 upload works fine. The problem is that after imageUpload returns, in handleSubmit(), it claims that the return value for imageUpload() is undefined. I suspect that it has to do with async/await, which I’m not too familiar with. Can any expert explain what I’m missing?

  async function imageUpload() {
 
    const params = {
      Bucket: BUCKET_NAME,
      Key: product.media.name,
      Body: product.media
    };
    s3.upload(params, function(s3Err, data) {
        if (s3Err) throw s3Err
        console.log(`File uploaded successfully at ${data.Location}`) // successfully get data.Location here
        return data.Location
    });

  }

  async function handleSubmit(event) {
    try {
      event.preventDefault();
      setLoading(true)
      setError('')
      const mediaUrl = await imageUpload()

      const url = `${baseUrl}/api/product`

      const { name, desc } = product
      const payload = { name, desc, mediaUrl } // mediaUrl is undefined here
      
      const response = await axios.post(url, payload)

    } catch(error) {
      catchErrors(error, setError)
    } finally {
      setLoading(false)
    }
  }

Answer

You have to wrap your imageUpload code inside promise and then pass the data to resolve callback that you want to return, and if there is some error you pass them in reject callback, throwing error in asynchronous task can give unexpected behaviour, so use reject callback there.

async function imageUpload() {

    const params = {
        Bucket: BUCKET_NAME,
        Key: product.media.name,
        Body: product.media
    };

    return new Promise((resolve, reject) => {
        s3.upload(params, function (s3Err, data) {
            if (s3Err) {
                reject(s3Error);
            }
            
            console.log(`File uploaded successfully at ${data.Location}`) // successfully get data.Location here
            resolve(data.Location);
        });
    });
}