Returning from a callback in an async function

Hi, I’m running a Meteor/Apollo/React stack and I have a mutation to upload an image to a database using the Meteor-Files package. I wish to return the resultant file ID which happens after insertion. write function docs here

async addImage(obj, { title, description, image }, { user }) {
     const userID = user._id
     var fileID
     const data = image.substring(image.indexOf(',') + 1)
     const x = await Images.write(Buffer.from(data, 'base64'), {
         fileName: 'image.png',
         type: 'image/png'
     }, (writeError, fileRef) => {
         if (writeError) {
             throw writeError
         }
         else {
             fileID = fileRef._id // I need this fileRef._id
         }
     })
     return fileID // I want to return fileRef._id
}

I am sending in the image as a base 64 string, and this write function is asynchronous. I thought I could block it by using the await keyword, but fileID remains undefined.

My other data relies on this fileID and thus I can’t do anything even in an update function in the useMutation hook because I don’t have access to the fileID.

How can I “block” these operations and return fileID only after the write function completes?

Thanks!

@ajaypillay To be able to await on Images.write, it will have to return a Promise, which it doesn’t currently. The Images.write API is using callbacks to control flow. If you really want to await it, you’ll want to wrap the call in a Promise like:

const fileID = await new Promise((resolve, reject) => {
  Images.write(Buffer.from(data, 'base64'), {
    fileName: 'image.png',
    type: 'image/png'
  }, (writeError, fileRef) => {
    if (writeError) {
      reject(writeError);
    } else {
      resolve(fileRef._id);
    }
  });
});

fileID will then have the result of fileRef._id.

1 Like

Thank you so much for the help! This works like a charm now.

Sincerely appreciated.

1 Like

Solved.