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).