How to output value from FileReader() - javascript

I would like to know how I can get the value from a filereader() function.
Here is the code :
$(document).ready(function(){
$('#file_input').on('change', function(e){
readFile(this.files[0], function(e) {
var txt = e.target.result
var lines = txt.split("\n");
var url_check = null;
$.each(lines, function(n, data) {
if (n == 0 && data != "") {
url_check = data
}
});
$('#output_field').text(url_check);
});
console.log(url_check)
});
});
function readFile(file, onLoadCallback){
var reader = new FileReader();
reader.onload = onLoadCallback;
reader.readAsText(file);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="file_input" type="file">
<div id="output_field"></div>
And I have this error :
Uncaught ReferenceError: url_check is not defined
My goal is to return the variable url_check to be accessible outside the readFile function
I also tried declaring url_check outside the readFile function like :
$(document).ready(function(){
$('#file_input').on('change', function(e){
var url_check = null;
readFile(this.files[0], function(e) {
var txt = e.target.result
var lines = txt.split("\n");
$.each(lines, function(n, data) {
if (n == 0 && data != "") {
url_check = data
}
});
$('#output_field').text(url_check);
});
console.log(url_check)
});
});
function readFile(file, onLoadCallback){
var reader = new FileReader();
reader.onload = onLoadCallback;
reader.readAsText(file);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="file_input" type="file">
<div id="output_field"></div>

Since you are declaring the url_check variable inside $(document).ready(function() ..., it means it is going to be accessible only there. A solution would be to declare the parameter globally, so that any changes from the function would be still visible. If you want to do something with the variable after it is assigned, you'd have to call the function there, immediately. Calling it before might result in null results, since the file wasn't processed yet. See the jsfiddle below. I tested it any it does what you want.
$(document).ready(function() {
$('#file_input').on('change', function(e) {
readFile(this.files[0], function(e) {
var txt = e.target.result
var lines = txt.split("\n");
if (lines && lines.length > 0)
url_check = lines[0];
$('#output_field').text(url_check);
console.log(url_check);
callbackPrint();
});
});
});
var url_check = null;
function readFile(file, onLoadCallback) {
var reader = new FileReader();
reader.onload = onLoadCallback;
reader.readAsText(file);
}
function callbackPrint() {
console.log("From testPrint: " + url_check);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="file_input" type="file">
<div id="output_field"></div>

Since the function is run asynchronously you should consider using a promise or a callback function to resolve/return the url_check in order to access it outside of the readFile function.
If you just want to log the value of url_check out console.log(url_check) must be placed inside the readFile

Related

Can not preview multiple uploading files in form

In a multipart form, I can preview a single uploading image using:
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
let image = new Image();
image.src = `${e.target.result}`;
image.className = "img-thumbnail"
let closeBtn = `<button type="button" class="close"></button>`;
let wrapper = $('<div class="image-wrapper" />');
$('#images-to-upload').append(wrapper);
$(wrapper).append(image);
$(wrapper).append(closeBtn);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#imgInput").change(function () {
readURL(this);
});
But I'd like to preview ALL uploading images, so I made this adjustment to the code above by adding a for loop:
function readURL(input) {
if (input.files && input.files[0]) {
let files = input.files;
for (var i = 0; i < input.files.length; i++) {
var reader = new FileReader();
reader.onload = function (e) {
let image = new Image();
image.src = `${e.target.result[i]}`;
image.className = "img-thumbnail"
let closeBtn = `<button type="button" class="close"></button>`;
let wrapper = $('<div class="image-wrapper" />');
$('#images-to-upload').append(wrapper);
$(wrapper).append(image);
$(wrapper).append(closeBtn);
}
};
reader.readAsDataURL(input.files[i]); // error here
}
}
But now I get this error:
143 Uncaught TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'
How can I fix this?
It's because the reader.readAsDataURL(input.files[i]); is outside the loop. But this is not how you do this. The FileReader can process only one file at the time. This means you have to create an instance of the FileReader for each image in the input.
I would suggest to split it into 2 functions for readability.
function previewImage(file) {
const reader = new FileReader();
reader.onload = function (e) {
let image = new Image();
image.src = e.target.result;
image.className = "img-thumbnail";
let closeBtn = `<button type="button" class="close"></button>`;
let wrapper = $('<div class="image-wrapper" />');
$("#images-to-upload").append(wrapper);
$(wrapper).append(image);
$(wrapper).append(closeBtn);
};
reader.readAsDataURL(file);
}
function readURL(input) {
if (input.files.length) {
Array.from(input.files).forEach((file) => previewImage(file));
}
}
I made some changes:
if (input.files.length) { - the file input always have files FileList object so no need to check if it exists, and you just check if it has a length, meaning at least one file is present
Array.from(input.files) - transforms FileList into a regular array fo you can use array functions, like forEach
The rest is pretty much the same. In image.src = e.target.result;, there's no need to make it string as it is already a string. Also the result set on the FileReader class cannot be array.

InnerText from event.target event not returning the text from target

I am trying to access only the text from an event.target but using innerText does not return the text. It returns undefined or blank.
Here's what I've tried.
function init(){
document.getElementById('fileInput').addEventListener('change', handleFileSelect); //'change' refers to when the file changes, 2nd argument calls function
}
function handleFileSelect(event){
const reader = new FileReader();
reader.onload = (evt)=>{
console.log(evt.target.result);
// console.log(evt.target.result.innerText);
document.getElementById('fileContent').textContent = evt.target.result;
};
reader.onerror = ()=>{
console.log("ERROR READING FILE");
};
reader.readAsText(event.target.files[0]); //takes only the first element (file) uploaded
}
window.onload = init; //when everything loads
I have also tried
console.log(evt.target.innerText)
But still does not work. Does anyone know why?
JQuery Verison
function getTextFromHTML(htmlText) {
var temp = $('<div>');
var text = temp.html(htmlText).text();
temp.remove();
return text;
}
function init() {
document.getElementById('fileInput').addEventListener('change', handleFileSelect);
}
function handleFileSelect(event) {
const reader = new FileReader();
reader.onload = (evt) => {
var htmlText = evt.target.result;
document.getElementById('fileContent').textContent = getTextFromHTML(htmlText);
};
reader.onerror = () => {
console.log("ERROR READING FILE");
};
reader.readAsText(event.target.files[0]);
}
window.onload = init;
<input id="fileInput" type="file" />
<div id="fileContent"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Pure JavaScript Version
function getTextFromHTML(htmlText) {
var temp = document.createElement("div");
var html = temp.innerHTML = htmlText;
var text = temp.textContent;
return text;
}
function init() {
document.getElementById('fileInput').addEventListener('change', handleFileSelect);
}
function handleFileSelect(event) {
const reader = new FileReader();
reader.onload = (evt) => {
var htmlText = evt.target.result;
document.getElementById('fileContent').textContent = getTextFromHTML(htmlText);
};
reader.onerror = () => {
console.log("ERROR READING FILE");
};
reader.readAsText(event.target.files[0]);
}
window.onload = init;
<input id="fileInput" type="file" />
<div id="fileContent"></div>
To get the result from a FileReader you should just use reader.result.
Like so (this is your code, working completely fine):
function init(){
document.getElementById('fileInput').addEventListener('change', handleFileSelect); //'change' refers to when the file changes, 2nd argument calls function
}
function handleFileSelect(event){
const reader = new FileReader();
reader.onload = (evt)=>{
document.getElementById('fileContent').textContent = evt.target.result;
};
reader.onerror = ()=>{
console.log("ERROR READING FILE");
};
reader.readAsText(event.target.files[0]);
}
window.onload = init;
<input type="file" id="fileInput" />
<div id="fileContent">file content</div>
If this doesn't work as intended on your end, check here if your browser supports the FileReader API: https://caniuse.com/#feat=filereader

Change this code from FileReader() to URL.createObjectURL

I see this particular code everywhere on Stackoverflow and many suggested that it needs to be converted from FileReader() to URL.createObjectURL Doing so will make it faster and the links will be shorter. But I have yet to find a working solution. (It's an image preview script that shows image thumbs on upload).
Can somebody help me convert it?
<script>
$(window).load(function(){
function readURL() {
var $input = $(this);
var $newinput = $(this).parent().parent().parent().find('.portimg ');
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
reset($newinput.next('.delbtn'), true);
$newinput.attr('src', e.target.result).show();
$newinput.after('<div class="delbtn delete_upload" title="Remove"><span class="bbb-icon bbb-i-remove2"></span></div>');
$("form").on('click', '.delbtn', function (e) {
reset($(this));
});
}
reader.readAsDataURL(this.files[0]);
}
}
$(".file").change(readURL);
function reset(elm, prserveFileName) {
if (elm && elm.length > 0) {
var $input = elm;
$input.prev('.portimg').attr('src', '').hide();
if (!prserveFileName) {
$($input).parent().parent().parent().find('input.file ').val("");
//input.fileUpload and input#uploadre both need to empty values for particular div
}
elm.remove();
}
}
});
</script>
If I understand you mean correctly, you may want to use URL.createObjectURL function like this:
// your url will look like this
// blob:http://example.com/a298356a-ad76-4353-a35f-b6e22a0e792f
var url = URL.createObjectURL(this.files[0]);
Full code:
function readURL() {
var $input = $(this);
var $newinput = $(this).parent().parent().parent().find('.portimg ');
if (this.files && this.files[0]) {
var url = URL.createObjectURL(this.files[0]);
reset($newinput.next('.delbtn'), true);
$newinput.attr('src', url).show();
$newinput.after(`
<div class="delbtn delete_upload" title="Remove">
<span class="bbb-icon bbb-i-remove2"></span>
</div>
`);
$("form").on('click', '.delbtn', function (e) {
reset($(this));
});
}
}

how to provide value to the filereader in jquery

This is my below function i want to directly provide value to file reader which will read csv file from c:\mp.csv and perform it task.
$("#csv").bind("change", function (event) {
var reader = new FileReader();
reader.onload = function (theFile) {
try {
alert(theFile.target.result);
var input = $.csv.toArrays(theFile.target.result);
} catch (e) {
alert("CSV Parse error.");
return;
}
$("#output").pivotUI(input, {
renderers: $.extend(
$.pivotUtilities.renderers,
$.pivotUtilities.gchart_renderers,
$.pivotUtilities.d3_renderers)
});
};
reader.readAsText(event.target.files[0]);
});

how to loop this function?

Thanks to some help on here I have a way of previewing images selected for and upload using:
<input type='file' name="files[]" onchange="readURL(this);" multiple />
<div id="previews"></div>
<script>
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
var container = $('#previews');
var image = $('<img>').attr('src', e.target.result).width(150);
image.appendTo(container);
};
reader.readAsDataURL(input.files[0]);
}
}
</script>
I was wondering how to loop this function for each file selected on the input? I just don't see where to use something like .each()
edit:
am trying this.. but its wrong somewhere, as it displays 2 previews but both of the same image?
function readURL(input) {
$.each(input.files,function(i) {
var reader = new FileReader();
reader.onload = function (e) {
var container = $('#previews');
var image = $('<img>').attr('src', e.target.result).width(150);
image.appendTo(container);
};
reader.readAsDataURL(input.files[0]);
});
}
input.files is a FileList, which acts like an array.
You can use jQuery.each on it like any other array.
You just need to loop over the last line, where the file is selected.
function readURL(input) {
var reader = new FileReader();
reader.onload = function (e) {
var container = $('#previews');
var image = $('<img>').attr('src', e.target.result).width(150);
image.appendTo(container);
};
$.each(input.files,function(i) {
reader.readAsDataURL(input.files[i]);
});
}

Categories

Resources