Filereader JS API not reading files properly - javascript

I have written the following code to read text from any csv or text file. However it sometimes reads successfully and stores in the variable and sometimes doesn't. Is there something missing in my code.
groupCsvData = [];
$('#add-group-upload').change(function() {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function(e) {
var text = reader.result;
groupCsvData = [text];
};
reader.readAsText(file);
)};

Related

Read Simple JSON file (almost done)

I have a input and when I load it shows the file right in console.log.
But how do I get the actual json data from the file??
$('#importFlow').change(function () {
var files = event.target.files;
var file = files[0];
console.log(file);
console.log(JSON.parse(file)); //doesn't work
});
You'd need to use the FileReader API.
$('#importFlow').change(function () {
var files = event.target.files;
var file = files[0];
var reader = new FileReader();
reader.onload = function(event) {
var jsonObject = JSON.parse(event.target.result);
console.log(jsonObject); // Logs the parsed JSON
}
reader.readAsText(file);
});
You can read actual file content like this:
$('#importFlow').change(function () {
var files = event.target.files;
var reader, fileContent;
if (this.files)
{
reader = new FileReader();
reader.onload = function (e)
{
fileContent = e.target.result;
}
reader.readAsDataURL(this.files[0]);
}
});
In the above code, you can get the actual file data in the "fileContent" variable.

How can I read a file from an HTML input with js-xlsx?

I have an angular application where I am trying to read and parse a .xlsx file resorting to the js-xlsx JavaScript library. However I am having trouble opening the file on the JavaScript side.
On my html I have a simple input of type file that opens a file chooser where the user can choose an appropriate file. I had trouble using angular directives to send the file to a function on my controller, because ng-change would not update when the user chose a file only when the button of the input is pressed. I ended up having to resort to a mixture of plain old JavaScript together with some angular by adding 'onchange="angular.element(this).scope().handleFile(this)"' to my input.
add-quotation.html:
<div class="container-fluid" ng-controller="addQuotationController">
...
<input type="file" id="file" class="" onchange="angular.element(this).scope().handleFile(this)">
...
</div>
This solved my problem of not being able to send the file from the HTML to the JavaScript side of things. However, I'm having trouble opening the file. I have tried many examples from the official documentation but I haven't succeeded in making it work. This is my current code:
add-quotation.component.js:
$scope.handleFile = function(e) {
var files = e.target.files;
var i,f;
for (i = 0, f = files[i]; i != files.length; ++i) {
var reader = new FileReader();
var name = f.name;
reader.onload = function(e) {
var data = e.target.result;
var workbook = XLSX.read(data, {type: 'binary'});
/* DO SOMETHING WITH workbook HERE */
};
reader.readAsBinaryString(f);
}
}
I tried to debug and found out that the file does indeed get into the method but then an exception occurs when trying to access "e.target.files;"
I'm completely lost in how to fix this and the examples that I've seen are of no help. What am I doing wrong?
You are looking for wrong object rather you should be using e.files. This is because e represents the <input> element; aka the value of this in your onchange attribute: onchange="angular.element(this).scope().handleFile(this)"
$scope.handleFile = function(e) {
console.log(e.files);
var files = e.files;
var i,f;
for (i = 0, f = files[i]; i != files.length; ++i) {
var reader = new FileReader();
var name = f.name;
reader.onload = function(e) {
var data = e.target.result;
var workbook = XLSX.read(data, {type: 'binary'});
/* DO SOMETHING WITH workbook HERE */
};
reader.readAsBinaryString(f);
}
}
you don't need FileReader(), instead use Blob.arrayBuffer()
$scope.handleFile = async function(e) {
var workbook = XLSX.read(await e.files.arrayBuffer(), {type: 'binary'});
// .....
}

How to get the filename from the Javascript FileReader?

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');

javascript file type not caught?

I am using the javascript file api to read a file and I want to get its type out. I am mainly using it to upload audio and video files. However when i upload amr, 3gp, and aac audio files, javascript can't figure out the filetype. I need to know the filetypes for the different audio formats as I use the files differently depending on the format. Is there anyway for me to figure out the format for the above mentioned files? I have supplied the code I use below.
var f = this.files[0];
var fr = new FileReader();
fr.onload = function (ev2) {
console.dir(ev2);
//$('#image').attr('src', ev2.target.result);
//extra[extra.length] = ev2.target.result;
extra[extra.length] = ev2.target.result;
var splitted = ev2.target.result.split(','); //get the type
fileType[fileType.length] = splitted[0];
console.log("splitted[0]: "+splitted[0]);
console.log("f.type: "+f.type);
};
fr.readAsDataURL(f);
regards
Try this code:Source
Demo
JSFiddle Example
var file = fileInput.files[0];
var textType = /text.*/;
if (file.type.match(textType)) {
var reader = new FileReader();
reader.onload = function(e) {
//onload code
}
reader.readAsText(file);
} else {
alert( "File not supported!");
}
or also this code:
var file = $("#inputFile")[0].files;
alert(file[0].type);

Using Javascript FileReader with huge files

I have a problem using the Javascript FileRead trying to read huge files.
For example, I have a text file of 200mb and everytime I read this file the code stops working.
Its possible to read the text file, but for example ONLY the first 10 lines or stop reading after 10mb?
This is my code:
var file = form.getEl().down('input[type=file]').dom.files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
data = e.target.result;
form.displayedData=data;
};
})(file);
reader.readAsText(file);
The e.target.result always has the whole data of the file.
What can I do here?
Thx
This will only read the first 10 mb:
var file = form.getEl().down('input[type=file]').dom.files[0];
var reader = new FileReader();
reader.onload = function(e) {
var data = e.target.result;
form.displayedData = data;
};
reader.readAsText(file.slice(0, 10 * 1024 * 1024));

Categories