My code -
$selectFile = $('<input type="file">');
$selectFile.click(function () {
this.value = null;
});
$selectFile.change(function(event){
var reader = new FileReader();
reader.readAsDataURL(event.target.files[0]);
reader.onloadend(function(e){
alert(e.result);
});
});
I am getting object is not a function error at reader.onloadend line.
Can anyone help please.
You need to change your onloadend method to onload. Also you need to set it to a function, not a parameter. To get the url/data you want use e.target.result not just e.result. Finally, I'd place the readAsDataURL after setting the method to make sure that it fires.
$selectFile.change(function(event){
var reader = new FileReader();
reader.onload = function(e){
alert(e.target.result);
};
reader.readAsDataURL(event.target.files[0]);
});
DEMO
Related
I simply want to get my HTML file input as a binary to save it in my SQL SERVER. The code below,apparently solves my problem,but i can't get "reader.readAsBinaryString(input.files[0])" and store in a variable.
It just console.log the input.files[0] ,but i need to store it.
Also,I'm not used to FileReader(),so any tips on how to use it are welcome.
Does this function uses the actual file being uploaded,or does it get the path to it?
The code is simple:
<input type="file" id="myFile" name="myFile">
JS:
$("#myFile").change(function (event) {
var input = event.target;
var reader = new FileReader();
reader.onload = function () {
console.log(reader.result);
};
fileToSave = reader.readAsBinaryString(input.files[0]);
});
readAsBinaryString doesn't return anything. What it does do is tell the FileReader to begin reading the file. When that process finishes, you can see the data you're reading in the result property of the FileReader object.
Which you've observed is available in the onload event:
reader.onload = function(){
console.log(reader.result);
};
Since that event is when the data is available, then that event is where you can read that data. For example:
reader.onload = function(){
fileToSave = reader.result;
console.log(fileToSave);
};
Of course then the next question becomes... When/where do you attempt to use the value in fileToSave. Keep in mind that this is an asynchronous operation. If you're trying to use the data in fileToSave right away then of course it won't contain the data that is later available in this onload event.
Whatever operation needs to use that data, that operation would have to happen after this event. For example:
reader.onload = function(){
fileToSave = reader.result;
console.log(fileToSave);
someOtherOperation();
};
or perhaps even:
reader.onload = function(){
const fileToSave = reader.result;
console.log(fileToSave);
someOtherOperation(fileToSave);
};
I'm loading multiple files with an input and I have this:
function getAsText(fileToRead, index) {
var reader = new FileReader();
reader.onload = loadHandler;
reader.onerror = errorHandler;
reader.readAsText(fileToRead);
}
In fileToRead there is the file[x]
My load handler look this way:
function loadHandler(event) {
var csv = event.target.result;
processData(csv);
}
And this works for one file. The problem is that I want to add an 'index' parameter to the loadHandler to know which file I'm reading. So I tried this:
reader.onload = loadHandler(this.event, index);
but this.event isn't working and loadHandler receives and empty event so it fails in 'event.target.result'
What should be the event?
Thanks.
You can use a closure callback like
function getAsText(fileToRead, index) {
var reader = new FileReader();
reader.onload = function () {
loadHandler(event, index)
};
reader.onerror = errorHandler;
reader.readAsText(fileToRead);
}
function loadHandler(event, index) {
var csv = event.target.result;
processData(csv);
}
I'm using the Javascript FileReader to load an image in the browser:
e = e.originalEvent;
e.dataTransfer.dropEffect = 'copy';
this.documentFile = e.dataTransfer.files[0];
var reader = new FileReader();
reader.onloadend = function () {
if (reader.result) {
console.log(reader);
$('#theImage').attr('src', reader.result);
}
};
reader.readAsDataURL(this.documentFile);
This works fine. I now want to get the original filename of the image, but I've got no clue how and looking around the internet I can't find anything either?
Does anybody know how I can get the filename through the FileReader? All tips are welcome!
This is prob not the best solution, BUT it worked for me.
var reader = new FileReader();
reader.fileName = file.name // file came from a input file element. file = el.files[0];
reader.onload = function(readerEvt) {
console.log(readerEvt.target.fileName);
};
Not the best answer, but a working one.
I just faced the same issue, here's how I fixed it:
Using FileReader
const reader = new FileReader();
reader.readAsDataURL(event.target.files[0]); // event is from the HTML input
console.log(event.target.files[0].name);
The selected answer will work, but I personally prefer to prevent assigning unknown properties to existing objects.
What I do is using the built-in Map object to store connections between FileReader and its File. It works great, because Map allows the key to be anything, even an object.
Consider this example with drag&drop on the window, where multiple files can be dropped at the same time:
// We will store our FileReader to File connections here:
const files = new Map();
window.addEventListener('drop', e => {
e.preventDefault();
for (const file of e.dataTransfer.files) {
const reader = new FileReader();
files.set(reader, file);
reader.addEventListener('load', e => {
// Getting the File from our Map by the FileReader reference:
const file = files.get(e.target);
console.log(`The contents of ${file.name}:`);
console.log(e.target.result);
// We no longer need our File reference:
files.delete(e.target);
});
reader.readAsText(file);
}
});
window.addEventListener('dragover', e => {
e.preventDefault();
});
And voilĂ , we made it without altering our FileReader objects!
I got the filename and filesize through the FileReader this way
First of all, the reader is a javascript FILE API specification that is so useful to read files from disc.
In your example the file is readed by readAsDataURL.
reader.readAsDataURL(this.documentFile);
var name = this.documentFile.name;
var size = this.documentFile.size;
I tried on my site where use this.files[0] instead and worked fine to catch the name and the size with jQuery into an input element.
reader.readAsDataURL(this.files[0]);
$("#nombre").val(this.files[0].name);
$("#tamano").val(this.files[0].size);
I tried the solution of #Robo Robok but was unable to get this to work in my Angular Application. With this as inspiration I came up with the following and wonder if this is a correct approach. Me, I'm a bit skeptic because each upload gets there own FileReader
export class ImageFileUpload {
imageData: any;
imageName!: string;
fileReader!: FileReader;
}
selectedFiles!: FileList | null;
previews: Array<ImageFileUpload> = [];
uploadRenewals(event: any) { // event of html
const target = event.target as HTMLInputElement;
this.selectedFiles = target.files;
if (this.selectedFiles) {
const numberOfFiles = this.selectedFiles.length;
for (let i = 0; i < numberOfFiles; i++) {
const currentSelectedFile = this.selectedFiles[i];
const newImageFile = new ImageFileUpload();
newImageFile.imageName = currentSelectedFile.name;
newImageFile.fileReader = new FileReader();
newImageFile.fileReader.onload = (e: any) => {
newImageFile.imageData = e.target.result;
};
newImageFile.fileReader.readAsDataURL(currentSelectedFile);
this.previews.push(newImageFile);
}
}
}
}
HTML Page
<input #fileInput (change)="uploadRenewals($event)" multiple type="file">
<div class="slider">
<div *ngFor="let preview of previews; let idx = index">
<img [src]="preview.imageData" [alt]="preview.imageName">
</div>
</div>
One other way is to modify the FileReader() object instance with your own desired property. Adding a key like reader.myOwnFileName gets you access to that in the onload callback.
const reader = new FileReader();
reader.onload = function() {
console.log("Loaded file '" + reader.myOwnFileName + "' contents: ");
console.log(reader.result); // output file contents of chosen file.
};
reader.readAsText(this.files[0]); // use readAsText(), readAsDataURL() or other method.
// make your own key on the object instance:
reader.myOwnFileName = this.files[0].name;
If you want the filename to a variable:
var filename;
var reader = new FileReader();
reader.onloadend = function () {
if (reader.result) {
console.log(reader);
$('#theImage').attr('src', reader.result);
filename = reader.result;
}
};
reader.readAsDataURL(this.documentFile);
If you want it to run in a function:
var reader = new FileReader();
reader.onloadend = function () {
if (reader.result) {
console.log(reader);
$('#theImage').attr('src', reader.result);
myfunctionafter(reader.result);
}
};
reader.readAsDataURL(this.documentFile);
If you want to get the info out inside another function:
var reader = new FileReader();
var filename = reader.onloadend = function () {
if (reader.result) {
console.log(reader);
$('#theImage').attr('src', reader.result);
return reader.result;
}
};
reader.readAsDataURL(this.documentFile);
There might be a problem when your reader.onloadend might finish before the function you are running it from. Then you should do two functions and trigger the myfunctionafter(reader.result); from inside
Or you could simply get the src after
var filename = $('#theImage').attr('src');
I ran the following function with a valid file object but it didn't work. The read text was an empty string. However, when I run the same commands via the console, it does work.
function(file) {
console.log(file)
var reader = new FileReader();
reader.readAsText(file);
console.log(reader.readyState);
console.log(reader.result);
}
Why?
I needed to set a callback for when the reader finishes reading the file, as this is done asynchronously.
function(file) {
console.log(file)
var reader = new FileReader();
reader.onload = function() {
console.log(reader.readyState);
console.log(reader.result);
}
reader.readAsText(file);
}
I need to loop this on a multiple file input:
var reader = new FileReader();
reader.onload = function (e) {
$('#pprev_0')
.attr('src', e.target.result);
};
reader.readAsDataURL(input.files[0]);
I tried this, but it does not work:
var fileCount = 0;
$("input[name='files[]']").each(function() {
var reader = new FileReader();
reader.onload = function (e) {
$('#pprev_'+fileCount)
.attr('src', e.target.result)
.css("display","block");
};
reader.readAsDataURL(input.files[fileCount]);
fileCount++;
});
alert() on fileCount output is a one time 0 on multiple file selection. no further alerts. If I take numbers instead of the fileCount var in code, it works at position. r.g. input.files[2] ...
Any idea?
When you do this: $("input[name='files[]']").each(function() { you are actually getting any elements that match the selector. In this case, you get your single multi file input (which is why you only see 1 alert. What you want to do is iterate over the files.
This page has code to do pretty much exactly what you want. I recommend you check it out:
http://www.html5rocks.com/en/tutorials/file/dndfiles/
To apply it to your situation, you would do something like this:
var files = $('#files')[0].files; //where files would be the id of your multi file input
//or use document.getElementById('files').files;
for (var i = 0, f; f = files[i]; i++) {
var reader = new FileReader();
reader.onload = function (e) {
$('#pprev_'+fileCount)
.attr('src', e.target.result)
.css("display","block");
};
reader.readAsDataURL(f);
}