Read multiple files using filereader in react js - reactjs

I tried to upload Multiple files and wants to read the content of the file for encrypt the data.
I can able to read the single file properly , but I can't do it while upload multiple files am getting error reader is busy.
If I create new Filereader while onloadend it gives me null value of content.
React JS - sample code:
let reader = new FileReader();
class FilReaderComp extends Component {
constructor(props) {
super(props);
this.state = {
}}
upLoadFileFolderFunc(e){
e.preventDefault();
let fileitemsList = e.target.files;
for (let i = 0; i < fileitemsList.length; i++) {
let fileitems = fileitemsList[i];
reader.onloadend = this.handleFileRead;
reader.readAsText(fileitems);
}
}
handleFileRead = (e) => {
const content = reader.result; here am reading content of the file
//here doing my function after getting content
}
render(){
return(
<input type="file" className="custom-file-input" style={{display:"hide"}}
onChange={this.upLoadFileFolderFunc} multiple/>
);}
export default withRouter(FilReaderComp);

Try wrapping your onload function in another function and enclose the filereader in the loop. Here the closure gives you access to each file being processed in turn via the variable f:
function openFiles(evt){
var files = evt.target.files;
for (var i = 0, len = files.length; i < len; i++) {
var file = files[i];
var reader = new FileReader();
reader.onload = (function(f) {
return function(e) {
// Here you can use `e.target.result` or `this.result`
// and `f.name`.
};
})(file);
reader.readAsText(file);
}
}

Related

How to pass a file to the server side as byte code in vue js?

I am trying to pass a file that is attached from client-side to server-side.
In order to get a file, I tried these below codes.
1)
var files = event.target.files;
var file = files[0];
2)
var image = new Image();
var reader = new FileReader();
var vm = this;
reader.onload = (e) => {
vm.image = e.target.result;
};
reader.readAsDataURL(file);
In the first one, 'file' contains only details about the file and it does not contain the file content and in the second one 'vm.image' file content is there, but it is not in byte code format. I want the file in byte code format in js which I can send in the body of an ajax call!
In order to get the base64 of the file input:
const files = e.target.files || e.dataTransfer.files;
const file = files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
this.image = reader.result.split(',')[1];
};
Here is an example:
document.getElementById('inputFile').addEventListener('input', function(e){
const files = e.target.files || e.dataTransfer.files;
const file = files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
this.image = reader.result.split(',')[1];
console.log(this.image)
};
})
<input type="file" id="inputFile"/>

Set component state, from unreachable variable

How I can get media.duration to live in a state environment ?
Right now I don't have access to it, even after trying to change state
handleClick(e) {
e.preventDefault();
var reader = new FileReader();
reader.readAsDataURL(this.state.uploadedFile);
reader.onload = function() {
var media = new Audio(reader.result);
media.onloadedmetadata = function() {
console.log(media.duration); // <-- THIS WORKS!!!!!!!!!!!!!!
};
};
console.log(media.duration) //<------THIS DOES NOT WORK!!!!!!!!!!
console.log("The link was clicked.");
console.log(this.state.duration);
}
from: How to get duration of video when I am using filereader to read the video file?
_________________________________________
I tried this but it did not work
this.setState({duration:media.duration},()=>{
console.log(this.state.duration)
})
It's because you use media variable is out of the scope.
Please try this one.
handleClick(e) {
e.preventDefault();
var reader = new FileReader();
reader.readAsDataURL(this.state.uploadedFile);
reader.onload = () => {
var media = new Audio(reader.result);
media.onloadedmetadata = () => {
console.log(media.duration); // <-- THIS WORKS!!!!!!!!!!!!!!
this.setState({duration: media.duration});
};
};
}

this.state is not working on reader.onload funtion in react js

I want to set state, but this.state is not working, can anyone please check this code, and help me what's issue in that, here is my code
save_import_permit() {
//alert('sdsdsd');
var file_name = jQuery('input[type=file]').val().split('\\').pop(); //jQuery('#permit_csv_file').prop('files')[0];
let files = jQuery('input[type=file]')[0].files[0];
console.log(files);
let reader = new FileReader();
let data = [];
reader.readAsDataURL(files);
reader.onload = function(e) {
console.log(e.target.result);
data.result = e.target.result;
data.action = 'Permity::saveImportCsvFile';
const url = 'admin-ajax.php';
const formdata = "file="+data.result+"&action="+data.action;
this.state({loading:'loading_show'})
return post(url,formdata,function (r) {
this.state({loading:'loading_hide'});
alert(r.data.msg)
}.bind(this));
}.bind(this);
}
You shouldn't attribute a value to the state using this.state, you should always use this.setState(), wichs is a build-in function of the react framework. Check this link to know better.
So you need to change
this.state({loading:'loading_show'})
to
this.setState({loading:'loading_show'})

I want access local file using file reader?

getImage(file) {
let context = this;
let reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
context.setState({
images: e.target.result,
});
};
})(file);
reader.readAsDataURL(file);
}
Error: TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'.
Files that comes from a <input /> of type file are stored in an array form.
If GetImage is the callback of the onChange event of your <input /> you need to extract it in the following form:
function getImage(event) {
const file = event.target.files[0];
// ...code
reader.readAsDataURL(file);
}

How to access a method in one object from a second object

Hi I'm new to javascript. I have one object ListModel and I am trying to access the addToModel method from a second object.
function ListModel(){
this.list = {};
}
ListModel.prototype.addToModel = function(s){
var items = s.split("\n");
for( var i =0; i<items.length-1; i++){
console.log(items[i] + "\n");
}
}
After extensive searching I have been unable to find a solution to this problem.
The second object is:
function ListMaker(){
this.model = new ListModel();
}
ListMaker.prototype.read = function(e){
var f = e.target.files[0];
if (f) {
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
this.model.addToModel(contents);
document.getElementById("ta").innerHTML = contents;
}
r.readAsText(f);
} else {
alert("Failed to load file");
}
}
In the read method I call:
this.model.addToModel(contents);
and the console returns
Cannot read property 'addToModel' of undefined
If I change the line to:
this.model = new ListModel().addToModel(contents);
then the method works as excpected.
Maybe I'm going about this the wrong way.
Any help would be appreciated.
The problem is this
http://javascriptplayground.com/blog/2012/04/javascript-variable-scope-this/
Once you call a function, this is no longer pointing to what you think it is.
You need to stash this in a local and then reference the local in your callback.
ListMaker.prototype.read = function(e){
var f = e.target.files[0];
var _this = this;
if (f) {
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
_this.model.addToModel(contents);
document.getElementById("ta").innerHTML = contents;
}
r.readAsText(f);
} else {
alert("Failed to load file");
}
}
See it in action: http://codepen.io/anon/pen/eZrYQj

Resources