Why is filereader not working? - javascript

I have a chat app built with socket.io and node.js. I have a function below for reading the file from the input and sending it to the server as a base64 string.
function readURL() {
if (this.files && this.files[0]) {
var FR= new FileReader();
FR.onload = function(e) {
$("img").attr("src", e.target.result);
socket.emit('image', e.target.result);
console.log(e.target.result);
};
FR.readAsDataURL( this.files[0] );
}
};
My HTML is as follows:
<input id="file" type='file' onchange="readURL()"/>
<img id="img">
However, upon uploading a file, nothing happens. No errors are recorded, and nothing is even logged to the console. Why is this so?

If the code you showed is all there is, then this will fix it
You need to pass a reference from the input's onchange method, here done using this and then add a parameter to the function, here done using el
Note, as this is a valid javascript operator, no error will be generated in your original code snippet.
You can read more about this here: JavaScript/Reference/Operators/this
function readURL(el) {
if (el.files && el.files[0]) {
var FR= new FileReader();
FR.onload = function(e) {
$("img").attr("src", e.target.result);
socket.emit('image', e.target.result);
console.log(e.target.result);
};
FR.readAsDataURL( el.files[0] );
}
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="file" type='file' onchange="readURL(this)"/>
<img id="img">

You are accessing selected file in wrong object.
If you have below html
<input id="file" type='file' onchange="readURL()"/>
then to get the file object in "readURL" method, try this:
var file = (((this.file || {}).files || [])[0]);
#Hundotte .. hope it will help you.

Related

How to print the name of the file from JavaScript fileReader?

I am trying to print the name of the uploaded image but it currently just previews the image but not actually printing the name of the file on the html. How can I make it print the name of the file from javascript fileReader function?
Here is my code in the main.js file
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#imagePreview').css('background-image', 'url(' + e.target.result + ')');
$('#imagePreview').hide();
$('#imagePreview').fadeIn(650);
}
reader.readAsDataURL(input.files[0]);
}
}
Here is the corresponding html code
<div class="image-section" style="display:none;">
<div class="img-preview">
<div id="imagePreview">
</div>
</div>
In the onload function you can get the file name.
reader.onload = function(e) {
console.log(e.target.fileName);
};
You can access it using name property. So as per your code its:
input.files[0].name

dataURL does not work for <a>

update: Finally I find out the reason myself, the reason is: actually I used Angular's ng-href at the same time, which prefix a unsafe to the data url, I have to config the compiler service to waive that restriction like:
.config( [
'$compileProvider',
function( $compileProvider )
{
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension):/);
// Angular before v1.2 uses $compileProvider.urlSanitizationWhitelist(...)
}
])
Which talks about here:
Angular changes urls to "unsafe:" in extension page
All:
What I want to do is read in a image as dataURL and give it to a tag as download:
<input type='file' name='doc' />
Download
<script>
var fileOBJ = $("input")[0]
.files[0];
var reader = new FileReader();
reader.onload = function(e){
$("a")[0].href=e.target.result;
}
reader.onerror = function(err){
console.log(err);
}
reader.readAsDataURL(fileOBJ);
</script>
The download always failed.
But if I use a <img> instead of <a>, then the image can shown up. I do not know what is wrong with the <a> link
Specify the atrribute download on the link. Like this:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='file' name='doc' />
<a download="filename" href="#">Download</a>
<script>
$("input").change(function() {
var fileOBJ = $("input")[0]
.files[0];
var reader = new FileReader();
reader.onload = function(e) {
$("a")[0].href = e.target.result;
// if you want to change the download filename
// $($("a")[0]).attr("download", "some other filename");
}
reader.onerror = function(err) {
console.log(err);
}
reader.readAsDataURL(fileOBJ);
})
</script>
You try to call readAsDataURL when there is any file selected, what throws an error. Use this method after you select some file.
var reader = new FileReader();
reader.onload = function(e){
$("a")[0].href = e.target.result;
};
reader.onerror = function(err){
console.log(err);
};
$('#inpFile').on('change',function(){
reader.readAsDataURL(this.files[0]);
});

value not getting stored in a variable

I have created a form where it asks user to upload his/her photo. But i am not able to save encoded value of my image. I want to save this value in a variable. I am not getting why my value is not getting saved in 'result' variable.
<html>
<body>
<input type="file" id="inp"/>
<img id="img" />
<div id="b64"></div>
<script type="text/javascript">
function EL(id) { return document.getElementById(id); }
function readFile() {
if (this.files && this.files[0]) {
var FR= new FileReader();
FR.onload = function(e) {
EL("img").src = e.target.result;
EL("b64").innerHTML = e.target.result;
};
var result = FR.readAsDataURL( this.files[0] );
console.log(result);
}
}
EL("inp").addEventListener("change", readFile, false);
</script>
</body>
</html>
Because event onload runs asynchronously, and you try to access the value synchronously, which result to undefined
move your logic inside onload, or if you want synchronous code style use promises instead.
<html>
<body>
<input type="file" id="inp"/>
<img id="img" />
<div id="b64"></div>
<script type="text/javascript">
function EL(id) { return document.getElementById(id); }
function readFile() {
if (this.files && this.files[0]) {
var FR= new FileReader();
FR.onload = function(e) {
EL("img").src = e.target.result;
EL("b64").innerHTML = e.target.result;
//put your code here
console.log(e.target.result);
};
FR.readAsDataURL( this.files[0] );
}
}
EL("inp").addEventListener("change", readFile, false);
</script>
</body>
</html>

HTML5 FileReader, read from local file

I want to read a local binary file. So, I do this
var file = new File([""], url);
var reader = new FileReader();
reader.onload = function () {
parse(reader.result);
}
reader.readAsArrayBuffer(file);
where url is a filepath like url="c:\temp\myfile.bin"
I don't have any errors, but something is wrong, because all data from my app disappear. What could be wrong ? Any ideas ?
Thanks!
I guess you have to use input type="file" for security reasons.
Here's a working example. For convenience it shows the opened file in the same browser window.
<html>
<body>
<script>
function readFile() {
var reader = new FileReader();
file = document.getElementById("uploadText").files[0];
reader.onload = function (ev) {
document.getElementById("obj").data = ev.target.result;
// parse(ev.target.result);
};
reader.readAsDataURL(file);
// reader.readAsArrayBuffer(file);
};
</script>
<div>
<input id="uploadText" type="file" onchange="readFile();" />
</div>
<object id="obj" data="" />
</body>
</html>

Trouble uploading binary files using JavaScript FileReader API

New to javascript, having trouble figuring this out, help!
I am trying to use the Javascript FileReader API to read files to upload to a server. So far, it works great for text files.
When I try to upload binary files, such as image/.doc, the files seem to be corrupted, and do not open.
Using dojo on the client side, and java on the server side, with dwr to handle remote method calls. Code :
Using a html file input, so a user can select multiple files to upload at once :
<input type="file" id="fileInput" multiple>
And the javascript code which reads the file content:
uploadFiles: function(eve) {
var fileContent = null;
for(var i = 0; i < this.filesToBeUploaded.length; i++){
var reader = new FileReader();
reader.onload = (function(fileToBeUploaded) {
return function(e) {
fileContent = e.target.result;
// fileContent object contains the content of the read file
};
})(this.filesToBeUploaded[i]);
reader.readAsBinaryString(this.filesToBeUploaded[i]);
}
}
The fileContent object will be sent as a parameter to a java method, which will write the file.
public boolean uploadFile(String fileName, String fileContent) {
try {
File file = new File("/home/user/files/" + fileName);
FileOutputStream outputStream = new FileOutputStream(file);
outputStream.write(fileContent.getBytes());
outputStream.close();
} catch (FileNotFoundException ex) {
logger.error("Error uploading files: ", ex);
return false;
} catch (IOException ioe) {
logger.error("Error uploading files: ", ioe);
return false;
}
return true;
}
I have read some answers suggesting the use of xhr and servlets to achieve this.
Is there a way to use FileReader, so that it can read files of any type (text, image, excel etc.) ?
I have tried using reader.readAsBinaryString() and reader.readAsDataUrl() (Decoded the base64 fileContent before writing to a file), but they did not seem to work.
PS :
1. Also tried reader.readAsArrayBuffer(), the resultant ArrayBuffer object shows some byteLength, but no content, and when this is passed to the server, all I see is {}.
This bit of code is intended to work on only newer versions of browsers..
Thanks N.M! So, it looks like ArrayBuffer objects cannot be used directly, and a DataView must be created in order to use them. Below is what worked -
uploadFiles: function(eve) {
var fileContent = null;
for(var i = 0; i < this.filesToBeUploaded.length; i++){
var reader = new FileReader();
reader.onload = (function(fileToBeUploaded) {
return function(e) {
fileContent = e.target.result;
var int8View = new Int8Array(fileContent);
// now int8View object has the content of the read file!
};
})(this.filesToBeUploaded[i]);
reader.readAsArrayBuffer(this.filesToBeUploaded[i]);
}
}
Refer N.M 's comments to the question for links to the relevant pages.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays
example
<html>
<head>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.3/jquery-ui.js"></script>
</head>
<body>
<script>
function PreviewImage() {
var oFReader = new FileReader();
oFReader.readAsDataURL(document.getElementById("uploadImage").files[0]);
oFReader.onload = function (oFREvent) {
var sizef = document.getElementById('uploadImage').files[0].size;
document.getElementById("uploadPreview").src = oFREvent.target.result;
document.getElementById("uploadImageValue").value = oFREvent.target.result;
};
};
jQuery(document).ready(function(){
$('#viewSource').click(function ()
{
var imgUrl = $('#uploadImageValue').val();
alert(imgUrl);
//here ajax
});
});
</script>
<div>
<input type="hidden" id="uploadImageValue" name="uploadImageValue" value="" />
<img id="uploadPreview" style="width: 150px; height: 150px;" /><br />
<input id="uploadImage" style="width:120px" type="file" size="10" accept="image/jpeg,image/gif, image/png" name="myPhoto" onchange="PreviewImage();" />
</div>
Source file
</body>
</html>

Categories

Resources