SeekanDestroy
SeekanDestroy

Reputation: 611

Async issues with AWS SDK. Await not waiting

I'm having troubles while trying to upload images from device (React Native Expo). Upload itself goes well, but I depend on the response to get the publication URL, and I'm sending that info to my backend.

The problem is that uploading images is an async function, which requires to await for the answer, and that's not happening. Cannot figure out why.

Here is the code:

export async function uploadImageOnS3(file) {
    const s3bucket = new S3({
    accessKeyId: "",
    secretAccessKey: "",
    Bucket: "",
    signatureVersion: "v4",
    });
    s3bucket.createBucket(() => {
    let contentDeposition = 'inline;filename="' + file.fileName + '"';

    const params = {
      Bucket: "",
      Key: file.fileName,
      Body: file.payload,
      ContentDisposition: contentDeposition,
      ContentType: file.type,
    };
    s3bucket.upload(params, (err, data) => {
      if (err) {
        console.log("error in callback " + err);
      }
      console.log("success");
      return data;
    });
  });
}

Here I'm returning "data" object which contains all required info.

Here is the trouble:

async function startPostingProcess(e) {
    e.preventDefault();
    const validation = await validateGeoLocation(geoLocation);
    
    if (validation.data.message) {
     
      setMessage(validation.data.message);
    } else {
      const imageToUpload = await getImageFromDevice(images);
     const location = await uploadImageOnS3(imageToUpload) //Here "await" is not waiting
      const newPost= {
        postName,
        postDesc,
        postApproxLocation,
        geoLocation,
        uploadImage: location.Location //Unhandled promise rejection: TypeError
        author: userInfo.username,
      };
      
       await createPost(newPost);
      setMessage(POST_CREATED);  
    }
  }

As I said, upload goes well, and required data is consoled out, but only after Unhandled promise rejection

Not getting what I'm doing wrong, "uploadImageOnS" startPostingProcess is a async function which awaits to uploadImageOnS3, which is also a async function. I tried returning a Promise in uploiadImageOnS3 which resolves with required data but getting same behavior.

What's wrong here?

EDIT: Tried suggested approach so code looks as follows:

export async function uploadImageOnS3(file) {
    const s3bucket = new S3({
    accessKeyId: "",
    secretAccessKey: "",
    Bucket: "",
    signatureVersion: "v4",
    });
    let contentDeposition = 'inline;filename="' + file.fileName + '"';

    const params = {
      Bucket: "",
      Key: file.fileName,
      Body: file.payload,
      ContentDisposition: contentDeposition,
      ContentType: file.type,
    }
      await s3bucket.createBucket().promise();
      const data = await s3bucket.upload(params).promise();
      return data;
  
    }

Now I'm getting [Unhandled promise rejection: MissingRequiredParameter: Missing required key 'Bucket' in params]. But I can see how params.Bucket contains a string with my S3 Bucket's name.

Upvotes: 0

Views: 1141

Answers (1)

Niyoko
Niyoko

Reputation: 7672

Nearly all AWS SDK methods return AWS.Request (see docs). You need to call .promise() method and await that returned promise. You don't need to pass callback.

Your uploadImageOnS3 become,

export async function uploadImageOnS3(file) {
  // skip

  await s3bucket.createBucket().promise();

  const params = /*skip*/;
  await s3bucket.upload(params).promise();
}

Upvotes: 1

Related Questions