0

My uploadPhoto function should return the id (int) of the photo that has been uploaded.

so inside my main function I've got let photoId = await uploadPhoto(image, name);

here's the code of the uploadPhoto function: First attempt

async function uploadPhoto(image, name) {
    try {

        let file = fs.readFileSync( image );

        await client.uploadFile({
                    name: image,
                    type: "image/jpg",
                    bits: file
                }, function( error, data ) {
                    return data.id
                });

    } catch (err) {
        console.log(err);
    }
}

Second attempt

async function uploadPhoto(image, name) {
    try {

        let file = fs.readFileSync( image );

        function uploadF (callback){
             client.uploadFile(  { name: image, type: "image/jpg", bits: file } , function( error, data ) {
                return callback(data.attachment_id);
            });
        }

        let res = await uploadF(function (data){
           return data;
        });

    } catch (err) {
        console.log(err);
    }
}
10
  • 1
    Does this answer your question? How to return the response from an asynchronous call Commented Jun 30, 2022 at 11:45
  • 2
    @David It sounds like client.uploadFile function mandates a callback and it seems to call the callback without checking if it exists. When OP left it out, the equivalent of undefined(null, data) was called which would lead to an error like that. Commented Jun 30, 2022 at 12:01
  • 1
    Ah, in that case it looks like you'd need to take the approach of wrapping it in a manual Promise and using resolve and reject internally, and returning that Promise. Commented Jun 30, 2022 at 12:03
  • 1
    Aside from the original question, since you're already using Promises, be sure to change your readFileSync to something that is not sync, like const {readFile} = require('fs/promises'); + const file = await readFile(image); Commented Jun 30, 2022 at 12:17
  • 1
    Despite having your answer, I would encourage reading the answer that David shared. You'll be able to understand why your code didn't work and why the solution fixes it. You'll encounter callback- and Promise-based code a lot. Commented Jun 30, 2022 at 12:21

1 Answer 1

2

Your uploadFile function doesn't return a Promise. That means that putting await in front won't make it wait until it's done. But you can wrap the function with a little bit of code so a Promise is returned.

// Call "resolve()" when the asynchronous action is done
// call "reject()" when an error occurs.
const data = await new Promise((resolve, reject) => {
  client.uploadFile({
    name: image,
    type: "image/jpg",
    bits: file
  }, function( error, data ) {
    if (error) {
      reject(error);
      return;
    }
    resolve(data.id);
  });
});
console.log(data.id);

Alternatively to wrapping it yourself, there is a helper function to do it for you:

const { promisify } = require('util');

// ...

// The .bind() might not be needed or it might be.
// Hard to tell without knowing what library you're using.
const upload = promisify(client.uploadFile).bind(client);

// ...

const data = await upload({
  name: image,
  type: "image/jpg",
  bits: file
});
console.log(data.id);
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.