Kwinten
Kwinten

Reputation: 71

Saving a Sharp Promise to a variable returns pending

I'm trying to resize an image from a base64 encoded string. I can do this using c in nodejs. Sharp works with Promises, so I know I have to do async methods. After resizing, I need to convert it back to a base64 string. I usually do this by converting an image to a buffer, using the nodejs Buffer, then use the 'toString() method to convert it back to base64.

This is what my code looks like:

async function resizer(base64, width = 224, height = 224) {
  if (!base64) {
    throw console.error("not a base64 string")
  } else {
    const Buffer = require("buffer").Buffer
    let base64buffer = Buffer.from(base64, "base64")
    const image = await sharp(base64buffer)
      .resize({
        width: width,
        height: height,
        fit: sharp.fit.cover,
      })
      .rotate(90)
      .toBuffer()

    const newBase64 = image.toString("base64")

    return newBase64
  }
}
const resizedBase64 = resizer(base64Image).then((result) => {
  console.log(result)
  return result
})
console.log(resizedBase64)

The function takes a base64 string as an argument. It then gets converted to a buffer and I let sharp do it's thing.I then return the the newly generated string. When I store it as a variable, however, it returns a Promise {pending}. When I just console.log inside the .then() callback, it does log the new base64 string.

Anyone know how to fix this? I need to use the new base64 later in the code.

Thank you in advance!

Upvotes: 0

Views: 1676

Answers (1)

Ben
Ben

Reputation: 1371

You simply need to add an await to get the resolved value from the promise:

const resizedBase64 = await resizer(base64Image);

EDIT: What's important to understand here is that your resizer function contains some asynchronous code (from the Sharp library) which returns a promise. As such, your function will also always return a promise of the value, not the value itself, even if you use await inside it. The caller of your function will receive the promise and will have to await it to get its actual value.

When calling your function resizer, if you are not in an async context and cannot use await there are a couple of solutions available. Solution 1: use an IIFE

(async() => {
  const resizedBase64 = await resizer(base64Image);
  console.log(resizedBase64);
  // the rest of your code goes here
})();

Solution2: declare an async function (basically the same as previous)

async main() => {
  const resizedBase64 = await resizer(base64Image);
  console.log(resizedBase64);
  // the rest of your code goes here
});

main();

Solution 3: place your code inside the then callback

resizer(base64Image).then((resizedBase64) => {
  console.log(resizedBase64);
  // the rest of your code goes here
});

Upvotes: 1

Related Questions