1

I have this function that converts an image URL to a base64 image string. The thing is that the function needs a callback, and I use a console.log to print the string (which works), but I need the string to be saved in a variable. Here is the code:

function convertImageToBase64(imgUrl, callback) {
    const image = new Image();
    image.crossOrigin = 'anonymous';
    image.onload = () => {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        canvas.height = image.naturalHeight;
        canvas.width = image.naturalWidth;
        ctx.drawImage(image, 0, 0);
        const dataUrl = canvas.toDataURL();
        callback && callback(dataUrl);
    }
    image.src = imgUrl;
}

And here's how I call the function:

convertImageToBase64(imgEmpresa, console.log);
convertImageToBase64(imgPropia, console.log);

Both img variables are URL strings I obtain through other methods. It works perfectly fine, and the output of the console.log is the base64 string. But the thing is that I need that variable to be stored somewhere and I have literally no clue on how to do it.

I tried making a function to serve as callback that just returns the variable, but that doesn't work

Malice
  • 13
  • 3

4 Answers4

1

You need to "promisify" it:

async function convertImageToBase64(imgUrl, callback) {
    return new Promise(resolve => {

        const image = new Image();
        image.crossOrigin = 'anonymous';
        image.src = imgUrl;

        image.onload = () => {
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            canvas.height = image.naturalHeight;
            canvas.width = image.naturalWidth;
            ctx.drawImage(image, 0, 0);
            const dataUrl = canvas.toDataURL();
            resolve(dataUrl)
        }
    })
}

and then await convertImageToBase64(...) somewhere else.

See also How do I return the response from an asynchronous call?

gog
  • 10,367
  • 2
  • 24
  • 38
  • This worked for me, thank you so much. Btw, is there any repercussion for making all my functions async ? Since I needed to do it on my window.onload because of the "await" part – Malice Mar 30 '23 at 12:03
  • @Malice there's no good reason to make an ordinary function involving no asynchronous operations `async`. However it's a wonderful idea when you *are* dealing with asynchronous APIs, because it really cleans up code. – Pointy Mar 30 '23 at 12:04
1

I can think of two ways. 1) You return the value from the function and store the value outside. Or you do it already in the function.

function convertImageToBase64(imgUrl, callback) {
  return var;
}
localStorage.setItem('test', convertImageToBase64(imgUrl, callback));

or

function convertImageToBase64(imgUrl, callback) {
  // storeInLocalStorage
  localStorage.setItem('test', var);
}
console.log(localStorage.getItem('test'));
Maik Lowrey
  • 15,957
  • 6
  • 40
  • 79
0

There is no return in your function. You need to return that value.

function convertImageToBase64(imgUrl, callback) {
   // some magic ...
   return imgSrc;
}
Jax-p
  • 7,225
  • 4
  • 28
  • 58
0

Assuming you can not change the original function: Use a closure to store the value, or pass the function that needs to consume it later on.

var stored = "";
convertImageToBase64(imgEmpresa,  (d) => { stored = d; });
console.log(stored);
sfiss
  • 2,119
  • 13
  • 19