Home > Blockchain >  How to pass image data as base64 to a global variable after the input changes as has happend in an i
How to pass image data as base64 to a global variable after the input changes as has happend in an i

Time:03-01

I am very new to this concept of async ,await ,promise ..paradigms ..Please help me

I have an input field like this

I have a global variable var base64.How to fill base64 global variable with base encoded value. Inside the function in addEventListener reader.result shows base encoded value.How Can i pass it to outside global variable.I tried a lot .. as it seems to be a async function ..the behavior seems to be quiet different and seems very difficult in catching up and also I am not getting the expected result

 <input  type="file"  id="photo" accept="image/*" required  @change="UploadPhoto()" />

The change function of UploadPhoto() is ..{This i got from mozilla}

function UploadPhoto() {

  const file = document.querySelector('#photo').files[0];
  const reader = new FileReader();

  reader.addEventListener("load", function () {
    // convert image file to base64 string
    console.log(reader.result);
  }, false);

  if (file) {
    reader.readAsDataURL(file);
  }
}

Also I will be greatful if you can explain me the working of reader.addEventListener and reader.readAsDataURL(file); with the case of asynchronous behavioured ..I googled a lot but couldnt find an article with detailed explaination of these two functions.

CodePudding user response:

Wanting a global (in this case) is a symptom of not having the tools you need to do without it.

If you really needed a global, you could get it this way...

let b64Encoded;

function UploadPhoto() {
  const file = document.querySelector('#photo').files[0];
  const reader = new FileReader();

  reader.addEventListener("load", function () {
    // convert image file to base64 string
    b64Encoded = btoa(reader.result);
  }, false);

But, as you suppose, the modern way to do it is to use promises. This will make the code simpler to understand, and will prove an even better decision when you get to actually posting the encoded file...

First wrap the file reader in a promise. Here's a fine post on the subject, and here's the punchline (slightly modernized)

async function readAsDataURL(file) {
    return new Promise((resolve, reject) => {
        const fr = new FileReader();
        fr.onerror = reject;
        fr.onload = () => {
            resolve(fr.result);
        }
        fr.readAsDataURL(file);
    });
}

Use it like this:

// we don't need this anymore :-)
// let b64Encoded;

async function UploadPhoto() {
  const file = document.querySelector('#photo').files[0];
  const result = await readAsDataURL(file);
  const b64Encoded = btoa(result);  // stack var, as it should be!
  // insert real (promise-based) network code here
  return myNetworkLibrary.post(b64Encoded);
}

The addEventListener method on file reader is part of the old school async: It says: file reader is going to do i/o on a separate thread. It will you tell you when it's done (that's the "event" part) by calling a function you specify (that's the "listener" part), pass it a function to call (that's the "add" part).

  • Related