2

I am so frustrated. I have been trying to fix this nasty bug since yesterday but there is no progress. I wonder what am I doing wrong. This is what I want to do. After the user submits the form which has enctype of "multipart/form-data" I want to grab the image that he has uploaded, put that into my MinIO database ( really similar to AWS S3 ) and then generate a link that will be the user's profile link. The link generates properly but I can't find a method to save it to the Account.pictureUrl value. Your help will be highly appreciated. Thank you!

THE CODE HAS BEEN REMOVED DUE TO PRIVACY CONCERNS

  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Matt Nov 03 '20 at 08:17
  • use the promise api in minio by not supplying a callback function. Then you can use async/await as described ^ – Matt Nov 03 '20 at 08:20
  • Thank you for your comment. This is a good resource but this answer actually solved my question.[https://stackoverflow.com/a/64659057/14568956]. Again thank you for your comment –  Nov 03 '20 at 08:35

1 Answers1

2

It's not a bug. It's a feature. JavaScript IO is asynchronous. Your best bet is to make url return a promise, so you can take advantage of async/await. MinIOClient methods return a promise if no callback is passed, so use that.

// If a custom image was selected by the client set the picture URL to Firebase's  CDN
const url = async () => {
  // If the user has selected a file
  if (req.file) {
    // Upload user image to the database
    await MinIOClient.fPutObject("local", `${req.body.email}.png`, req.file.path, {
      "Content-Type": req.file.mimetype
    });

    // Getting the link for the object
    const presignedUrl = await MinIOClient.presignedGetObject("local", `${req.body.email}.png`, 24 * 60 * 60)
 

    return presignedUrl;
  }
  // If the user didn't select an image return a random image link(string) that will be used to serve default avatars from the server
  else {
    return avatarLinks[Math.floor(Math.random() * avatarLinks.length)];
  }
};

Then modify the controller

router.post("/", upload.single("avatar"), async (req, res) => {

    const pictureUrl = await url();

    let Account = new AccountSchema({
        // ... other values
        pictureUrl
    });
});
Adam Azad
  • 11,171
  • 5
  • 29
  • 70