[Javascript]How to save FileReader result into a variable



Commonly, FileReader is executed asynchronously, and some operation against the result is done in the onload event.

In this article, I am going to describe about how to save FileReader result into a global variable instead of processing in the onload event.





Common usage of FileReader

Commonly, FileReader is used as below.
Firstly, requesting to convert Blob(or File) to Data URL, and then processing the result in the onload event.

In this way, we have to write the continuation in the onload event.

let blob = new Blob(["hoge"], {type: 'image/png'})

let reader = new FileReader()
reader.readAsDataURL(blob)
reader.onload = function() {
    dataUrl = reader.result

    //some process against FileReader result
    .
    .
    .
}




Trying to save FileReader result into a global variable

When you try to save FileReader result into a global variable, you may come up with such as below code.
But it dose not work.

undefined would come in the dataUrl valiable.

let blob = new Blob(["hoge"], {type: 'image/png'})

let dataUrl = ''
let reader = new FileReader()
reader.readAsDataURL(blob)
reader.onload = function() {
    dataUrl = reader.result
}

console.log(dataUrl)  //undefined




Correct way to save FileReader result into a global variable

By using async/await and Promise, you can save FileReader result into a global variable.

The flow at the 6 line is like onload event resolve method ⇒ Promise settles.
We can save the result into a variable in the 7 line because await makes javascript waiting until Promise settles.

;(async function() {
    let blob = new Blob(["hoge"], {type: 'image/png'})
    
    let reader = new FileReader()
    reader.readAsDataURL(blob)
    await new Promise(resolve => reader.onload = () => resolve());
    dataUrl = reader.result
    
    console.log(dataUrl)  //Data URL
})()


await is only available in the async function. In the above code, I have used the async function as IIEF(immediately invoked function expression) by putting () at the last line.
When you want to use await, maybe you can try to enclose all code with async IIEF. (like below)

;(async function() {
    //some code
    //some code
    //some code
    //some code

    let blob = new Blob(["hoge"], {type: 'image/png'})
    
    let reader = new FileReader()
    reader.readAsDataURL(blob)
    await new Promise(resolve => reader.onload = () => resolve());
    dataUrl = reader.result

    //some code
    //some code
    //some code
    //some code
})()




Getting together FileReader process as a function.

We can get together FileReader process as a function, and then it would be more useful.

async function convert2DataUrl(blobOrFile) {
    let reader = new FileReader()
    reader.readAsDataURL(blobOrFile)
    await new Promise(resolve => reader.onload = () => resolve())
    return reader.result
}


You can use it as below. Procedural processing code has become crear.

;(async function() {
    //some code
    //some code
    //some code
    //some code

    let blob = new Blob(["hoge"], {type: 'image/png'})
    let dataURL = await convert2DataUrl(blob)

    //some code
    //some code
    //some code
    //some code
})()

async function convert2DataUrl(blobOrFile) {
    let reader = new FileReader()
    reader.readAsDataURL(blobOrFile)
    await new Promise(resolve => reader.onload = () => resolve())
    return reader.result
}




That is all. It was about how to save FileReader result into a variable.

Sponsored Link

You can subscribe by SNS

Sponcerd Link

Leave a Reply

*