HTML5 FileReader how to return result?
Reading happens asynchronously. You need to provide a custom onload
callback that defines what should happen when the read completes:
$(document).ready(function(){
$('#file_input').on('change', function(e){
readFile(this.files[0], function(e) {
// use result in callback...
$('#output_field').text(e.target.result);
});
});
});
function readFile(file, onLoadCallback){
var reader = new FileReader();
reader.onload = onLoadCallback;
reader.readAsText(file);
}
(See the Fiddle.)
Note that readFile
does not return a value. Instead, it accepts a callback function, which will fire whenever the read is done. The $('#output_field').text
operation is moved into the callback function. This ensures that that operation will not run until the reader's onload
callback fires, when e.target.result
will be filled.
Programming with callbacks is a bit difficult to get right at first, but it is absolutely necessary for implementing advanced functionality.
How to return the result of FileReader. in clojurescript
After much reading, I solved it using a callback function:
(ns lopezsolerluis.fits)
(defn read-file [file callback]
(let [js-file-reader (js/FileReader.)]
(set! (.-onload js-file-reader)
(fn [evt]
(let [result (-> evt .-target .-result)
array (js/Uint8Array. result)]
(callback array))))
(.readAsArrayBuffer js-file-reader file)))
Then read-file
is called from this:
(ns lopezsolerluis.annie-web)
(defn procesar-archivo [result]
(js/console.log "Bloques: " result))
(defn input-file []
[:input {:type "file" :id "fits" :name "imagenFits" :accept "image/fits"
:on-change (fn [this]
(if (not (= "" (-> this .-target .-value)))
(let [^js/File file (-> this .-target .-files (aget 0))]
(fits/read-file file procesar-archivo)))
(set! (-> this .-target .-value) ""))}])
I added the namespaces because it surprised me that the callback machinery worked even across namespaces. Well, maybe it shouldn't surprise me; but I am learning and was a new concept for me. :)
I answer my question in case it's useful for others (it costed me a lot! :))
HTML5 Filereader always returns empty string?
The FileReader
object is not ready yet. You need to add an onload
event listener to the reader and then make a call to the readAsText
method. You can then access the file contents from inside the callback function.
MDN docs - https://developer.mozilla.org/en-US/docs/Web/API/FileReader/result
function selectfile() {
myFile = document.getElementById("filelist").files[0];
reader = new FileReader();
reader.onload = () => {
myResult = reader.result;
alert(myFile.name);
alert(myResult);
alert(reader.error);
};
reader.readAsText(myFile); // only accessible when the FileReader is loaded
}
<input type="file" id="filelist" onchange="selectfile()">
Capture result of HTML5 FileReader when using promises in async
As the code is asynchronous in nature, you will have to wait for the result if you want to use it. In your case, you will have to wait until your promise is resolved. So your code should look like:
ngAfterViewInit(): void {
let image = new Image();
var promise = this.getBase64(this.fileObject, this.processImage);
promise.then(function(base64: string) {
console.log(base64);
image.src = base64;
let editor = new PhotoEditorSDK.UI.ReactUI({
container: this.editor.nativeElement
editor: {
image: image
}
});
});
}
I have changed following things:
- I moved code for
ReactUI
instantiation inside promise callback - Specified type of
base64
parameter asstring
- Fixed typo in
getBase64
function call, fromthis.processImage()
tothis.processImage
so it is passing callback function and not result ofprocessImage
function.
I hope this helps!
How to load FileReader result into HTML5 video for best compatibility across browsers & devices
I ended up just not using FileReader
for video, and just using URL.createObjectURL(file)
directly on the file and it is working.
onFileUpload({ file }) {
const URL = window.URL || window.webkitURL;
const vid = document.getElementById('#id-for-video-preview-element');
vid.src = URL.createObjectURL(file);
vid.load();
}
FileReader onload with result and parameter
Try wrapping your onload function in another function. Here the closure gives you access to each file being processed in turn via the variable f
:
function openFiles(evt){
var files = evt.target.files;
for (var i = 0, len = files.length; i < len; i++) {
var file = files[i];
var reader = new FileReader();
reader.onload = (function(f) {
return function(e) {
// Here you can use `e.target.result` or `this.result`
// and `f.name`.
};
})(file);
reader.readAsText(file);
}
}
For a discussion of why a closure is required here see these related questions:
- JavaScript closure inside loops – simple practical example
- Javascript infamous Loop issue?
Can't return value of fileReader result in AngularJS service
Its because img was not loaded yet. Here is a solution
.service('ReadLocalImageService', [function () {
this.openLocalImage = function (file, callback) {
var img = document.createElement("img");
var fileReader = new FileReader();
fileReader.onload = function (e) {
img.src = e.target.result;
callback(img.src);
};
fileReader.readAsDataURL(file);
};
}]);
We will pass a callback
function and receive img.src
as its param. To use it
ReadLocalImageService.openLocalImage(myImage, function(imgSrc) {
// use imgSrc
});
Related Topics
What's the Best Way to Make a D3.Js Visualisation Layout Responsive
How to Update State.Item[1] in State Using Setstate
Change Values in Array When Doing Foreach
Fastest Way to Convert JavaScript Nodelist to Array
Accessing Private Member Variables from Prototype-Defined Functions
Make React Useeffect Hook Not Run on Initial Render
How to Make a JSONp Request from JavaScript Without Jquery
Enabling Cross-Origin Resource Sharing on Iis7
Iterate Through Nested JavaScript Objects
Regex to Match All Instances Not Inside Quotes
Running JavaScript in Selenium Using Python
How to Auto-Scroll to End of Div When Data Is Added
Jquery Click Anywhere in the Page Except on 1 Div
HTML - Attributes VS Properties
How to Remove the "No File Chosen" Tooltip from a File Input in Chrome