Get value after reader onload - javascript

var image is not defined in alert :( please help , thank you so much!
handleBeforeUpload (file, event) {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (function () {
var f = reader.result;
});
var image = f;
alert(image)
var photo = {uri: image}

Your f variable is in scope of onload function callback. Define it outside of that function, where you define your reader variable, so it will be available in scope of handleBeforeUpload function
handleBeforeUpload (file, event) {
var reader = new FileReader();
var photo = null;
reader.readAsDataURL(file);
reader.onload = (function () {
f = reader.result;
photo = { uri: f }
});
}

Related

How I can get base64 string of image from FileReader

I am using below 2 methods but I am unable to get back base64 string from it.
function convertFileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
});
}
function previewProductImages(files){
let preveiwImagesTemplate = [];
for(let i=0; i<files.length; i++ ){
const uploadedImageBase64 = convertFileToBase64(files[i]);
/// WANT BASE64 HERE So I can pass that to another method
}
}
Replacement or better approches are welcome.
You should first assign a handler to the onload property - and then call the readAsDataURL() method, not the opposite.
function readFile(file)
{
return new Promise((resolve) =>
{
if (file.size)
{
const reader = new FileReader();
reader.onload = (e) =>
{
resolve({
binary: file,
b64: e.target.result,
});
};
reader.readAsDataURL(file);
}
});
}

Failed to execute 'readAsDataURL' on 'FileReader': the object is already busy reading Blobs

I want to upload multiple images. When I choose multiple images photoSelected function is called. I want to use base64 but it shows this error on console.
PhotoSelected (e){
Let files = e.target.files;
Let reader = new FileReader();
Let file;
For (let i=0; I<files.length ; i++){
file = files [i];
reader.onload = (file) => {
This.product.photo[i] = reader.result;
}
reader.readAsDataURL(file)
}
}
you defined the reader outside the for loop and use the same reader within the loop. this results in the reader being busy. You can solve this by creating one reader for each loop in its own scope, using an IIFE.
PhotoSelected (e){
let files = e.target.files;
let reader = new FileReader();
let file;
for (let i=0; I<files.length ; i++){
(function(file) {
var reader = new FileReader();
reader.onload = (file) => {
this.product.photo[i] = reader.result;
}
reader.readAsDataURL(file)
})(files[i]);
}
}
Since you are using let already and it uses block scope, you could also create a reader each loop using let.
PhotoSelected (e){
let files = e.target.files;
let file;
for (let i=0; I<files.length ; i++){
let reader = new FileReader();
file = files [i];
reader.onload = (file) => {
this.product.photo[i] = reader.result;
}
reader.readAsDataURL(file)
}
}

How to reset filefield after select file ExtJs

I try to reset filefield after select file with the same name, but it not work:
onUploadPhonesCSV: function (field, value, opts) {
var inputEl = field.fileInputEl.dom,
fileList = inputEl.files;
var file = fileList[0];
var vm = this.getViewModel();
console.log(value);
if (field.isValid()) {
var reader = new FileReader();
reader.onload = function (oFREvent) {
var myCsv = oFREvent.target.result;
vm.set('phones', myCsv);
field.setRawValue("");
};
reader.readAsBinaryString(file);
}
},
Also tried field.reset() it not work.
Help me please.

VueJS - Assigning value to this.property within callback

How can I force
this.json = reader.result;
to assign value to this.json properly in given scope?
Because the value is there, but it is not assigned.
<div id="app" >
<label class="text-reader"><input type="file" v-on:change="getFile($event)"></label>
{{ json }} // it's being set to "test" from getFile function.
</div>
Here's VueJS Code
new Vue
({
el: '#app',
data: {
json: {}
},
methods:
{
getFile: function(ev)
{
this.json = "test";
var file = ev.target.files[0];
var reader = new FileReader();
reader.onload = function(e)
{
this.json = reader.result;
console.log(this.json); // displays content properly
}
reader.readAsText(file);
}
}
});
What I've been trying so far is just adding some kind of handler
getFile: function(ev)
{
var file = ev.target.files[0];
var reader = new FileReader();
reader.onload = function(e)
{
this.callBackHandler(reader.result);
}
reader.readAsText(file);
},
callBackHandler: function(val)
{
console.log(val);
this.json = val;
}
It yells:
TypeError: this.callBackHandler is not a function
Also using callBackHandler as a param.
<label class="text-reader"><input type="file" v-on:change="getFile($event, callBackHandler())"></label>
getFile: function(ev, handler)
{
var file = ev.target.files[0];
var reader = new FileReader();
reader.onload = function(handler)
{
handler(reader.result);
}
reader.readAsText(file);
},
callBackHandler: function(val)
{
console.log(val);
this.json = val;
}
The getFile function should look like this:
getFile: function(ev, handler) {
var file = ev.target.files[0];
var reader = new FileReader();
reader.onload = (e => {
this.callBackHandler(reader.result);
})
}
or
getFile: function(ev, handler) {
var file = ev.target.files[0];
var reader = new FileReader();
var self = this;
reader.onload = function(e){
self.callBackHandler(reader.result);
}
}
or
getFile: function(ev, handler) {
var file = ev.target.files[0];
var reader = new FileReader();
reader.onload = function(e){
this.callBackHandler(reader.result);
}.bind(this)
}
Solution:
v-on:change="getFile($event)"
(...)
reader.onload = (x =>
{
this.callBackHandler(reader.result);
});

how to make the code wait inside the following async/await function?

I want to resize an image before uploading it to the server (with Firebase):
api.uploadPhoto = async (file = {}, field = {}) => {
const canvas = document.getElementById('canvas')
const img = document.createElement('img')
const reader = new FileReader()
let fileToUpload
reader.onload = function (e) {
img.src = e.target.result
pica.resize(img, canvas).then(result => {
fileToUpload = pica.toBlob(result, 'image/jpeg', 90))
})
}
reader.readAsDataURL(file)
// run the code below only when reader.onload has finished
return await imageUpload.toFirebase(fileToUpload, field)
}
The problem is that imageUpload.toFirebase is running before reader.onload. How to fix this?
move the upload in to the callback ...
api.uploadPhoto = async (file = {}, field = {}, callback) => {
const canvas = document.getElementById('canvas');
const img = document.createElement('img');
const reader = new FileReader();
let fileToUpload;
reader.onload = function (e) {
img.src = e.target.result;
pica.resize(img, canvas).then(result => {
fileToUpload = pica.toBlob(result, 'image/jpeg', 90));
});
reader.readAsDataURL(file);
callback(await imageUpload.toFirebase(fileToUpload, field));
}
};

Categories