A JavaScript beginner here. I would like to write a basic function that takes a path to a local text file and returns its contents. I am aware that this question has been asked like 1000 times now, for example here. But every single answer is different from each other, I have tried a few, and they don't seem to work. After googling for a bit, I was able to come up with the following solution
function readTextFile(path) {
var reader = new FileReader();
reader.onload = function(event) {
var contents = event.target.result;
console.log("File contents: " + contents);
};
reader.onerror = function(event) {
console.error("File could not be read! Code " + event.target.error.code);
};
var file = new File([path], { type: 'plain/text' });
reader.readAsText(file);
return contents
}
However, for some reason it outputs the path itself, not the contents. Please suggest how this code can be fixed, shortened, improved.
I also tried fetch but I get the infamous cross-origin request error, that I could not figure out how to solve easily.
EDIT:
Ok, I'll add a few more lines to make things more clear
index.html:
<input type="file" id="jsonAddressInput" value="enter address here">
script.js
function myFunction() {
var addressField = document.getElementById("jsonAddressInput");
var addressText = addressField.value;
console.log(addressText);
var textContentsOfFile = readTextFile(addressText)
//console.log(textContentsOfFile)
}
function readTextFile(path) {
var reader = new FileReader();
reader.onload = function(event) {
var contents = event.target.result;
console.log("File contents: " + contents);
};
reader.onerror = function(event) {
console.error("File could not be read! Code " + event.target.error.code);
};
var file = new File([""], path, { type: 'plain/text' });
reader.readAsText(file);
return contents
}
It was mentioned that I can use the results of the to get file contents. Please suggest how to fix
Here's an example how to read a local file:
function readJson(blob) {
var reader = new FileReader();
reader.onload = function(event) {
contents = event.target.result;
};
reader.onerror = function(event) {
console.error("File could not be read! Code " + event.target.error.code);
};
var file = new File(blob, { type: 'plain/text' });
reader.readAsText(file);
}
let contents
document.querySelector("input").addEventListener("change", (e) => {
contents = readJson(e.target.files);
})
document.querySelector("button").addEventListener("click", (e) => {
console.log(contents);
})
<input type="file">
<button>show contents</button>
If you want the contents of a remote file, use fetch
Related
i'm using below method to upload files to laravel backend
setFile(id, e) {
let self = this;
let reader = new FileReader();
reader.readAsDataURL(e.target.files[0]);
reader.onload = function () {
console.log(reader.result);
self.documentArray.forEach(function (element) {
if (id == element.id && reader.result) {
element.file = reader.result;
element.file_browse_name = e.target.files[0].name;
}
});
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
},
but when i select a file larger than 5mb or around, it doesn't add the element to the relevant object of the documentArray but it logs the result in console, so i cant add validation on backend. please give me a way to solve this problem
Maybe the problem is with your PHP settings. Check your upload_max_filesize and your post_max_size
Hello! I'am trying to make it work a function called loadDocument, who need a url of the loaded files from the user local computer to work. I'm writing an API to load document from local user computer, and show it on a web reader.
This is my upload button :
<input type="file" id="input" onchange="module.onLoadSelection();" alt="Browse" name="upload"/>
This is my function without fileReader :
var onLoadSelection = function () {
var select = document.getElementById('input');
if (select && select.value) {
var id= '';
var url = select.files.item(0).name;
module.loadDocument(url,id);
}
};
This is my function with fileReader :
var loadTest = function (input) {
var file = document.querySelector('input[type=file]').files[0];
console.log("file loaded! ->", file); // i can read the obj of my file
var reader = new FileReader();
var id = ''; // don't need rightnow
var url = reader.readAsDataURL(file);
console.log("url :", url); // show me undefined....
module.loadDocument(url,id);
}
What i am trying is to get the url of the loaded file from user computer to get my function loadDocument working. She need a url parameter to work.
loadDocument is an API function, i assume i can't get the filepath of my user due to security reason.
What do i need to change/update on my loadDocument(); function to work?
Edit : In fact, nothing to change. The correct way to read my file was :
<input type="file" id="input" onchange="module.onLoadSelection(this.files);" alt="Browse" name="upload"/>
var onLoadSelection = function (files) {
if (files && files.length == 1) {
var id = '';
var url = URL.createObjectURL(files[0]);
module.loadDocument(url,id);
}
};
Don't use a FileReader at all.
When you want to display a File (or a Blob) that is in the browser's memory or on user's disk, then all you need is to generate an URL that do point to this memory slot.
That's exactly what URL.createObjectURL(blob) does: it returns a Blob URI (blob://) that points to the data either in memory or on the disk, acting exactly as a simple pointer.
This method has various advantages over the FileReader.readAsDataURL() method. To name a few:
Store the data in memory only once, when FileReader would need it at reading, then generate a copy as an base64 encoded, and an other one at displaying...
Synchronous. Since all it does is to generate a pointer, no need to make it async.
Cleaner code.
const module = {
loadDocument: (url) => {
document.body.append(
Object.assign(
document.createElement('iframe'),
{ src: url }
)
)
}
};
document.querySelector('input[type=file]').addEventListener('input', function (evt) {
var file = this.files[0];
var url = URL.createObjectURL(file);
module.loadDocument(url);
});
<input type="file">
function PreviewFiles(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
//alert(e.target.result);
$('#pclogo').prop('src', e.target.result)
.width(200)
.height(200);
var base64result = e.target.result.split(',')[1];
$('input[name="logo"]').val(base64result);
};
reader.readAsDataURL(input.files[0]);
}
}
File objects have a readAsDataURL method.
Use that.
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener("load", function () {
doSomethingWithAUrl(reader.result);
}, false);
if (file) {
reader.readAsDataURL(file);
}
I am doing a file upload operation in React, and I need to read the file uploaded from the user and do some state changes according to this file. What I have right now is shown below and I need to need to access the variable startInt within the onload callback, but it is still not defined here using the IIFE
const file = document.getElementById("fileUpload").files[0];
if (file) {
const reader = new FileReader();
reader.readAsText(file, "UTF-8");
reader.onload = ((theFile) => {
const form = document.getElementById('fileUploadForm');
const start = datetimeToISO(form.Start.value);
const startInt = new Date(start).getTime();
return (e) => {
console.log(e.target.result);
//startInt is not defined here
}
})(file);
}
I followed this guide if it helps: https://stackoverflow.com/a/16937439/6366329
If you could point out my mistake that would be great. Many thanks in advance
you can access local var (but not class const like this.state.* or this .props.*).
so something like this you need:
var file = document.getElementById('inputID').files[0]
var Images = this.props.motherState.Images // Images is array
var reader = new FileReader();
reader.readAsDataURL(file); //
reader.onload = function () {
//console.log(reader.result);
if (file.type.match(/image.*/))
Images.push(reader.result) // its ok
// but this.props.motherState.Images.push(reader.result)
// return error like this:
// Images not define in this.props.motherState.Images
};
reader.onerror = function (error) {
//console.log('Error: ', error);
};
my project have this foldes:
-html
index.html
-css
-js
my.js
-pdf
test.pdf
I need to convert this "test.pdf" to base 64 and send by POST
I try use a function like this:
function getBase64() {
var reader = new FileReader();
var file = new File("/pdf/test.pdf","r");
reader.addEventListener("loadend", function() {
// reader.result contains the contents of blob as a typed array
reader.readAsDataURL(file);
reader.onload = function () {
console.log(reader.result);
return reader.result;
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
});
But I'm not the correct way to get past the folder path, or if I have to use another object and not File.
var file = new File("/pdf/test.pdf","r");
What's the best way to do it?
Thank you!
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');