Reputation: 209
Here is the code I am working on:
<!--HTML Code for referencing the file -->
<input type="file" name="file" id="file">
<script>
var store = [];
document.getElementById('file').onchange = function(){
var file = this.files[0];
var reader = new FileReader();
// Define the body of reader function
reader.onload = function(progressEvent){
// By lines
var lines = this.result.split('\n');
for(var line = 0; line < lines.length; line++){
// Store it in an array
store.push(lines[line]);
//console.log(store.length); // This line on being uncommented
// shows that store is being modified. The values getting printed
// are 1,2,3, ...... upto 16 (length of the input file)
}
};
// Read the file and store it in the var "store"
reader.readAsText(file);
console.log(store.length); // The problem appears here!!!!!
};
</script>
The problem is, even after choosing a file containing 16 sample numbers, the console prints the store.length value as 0. Why is the push command not affecting the var "store" ?
Upvotes: 0
Views: 2304
Reputation: 1032
The onload
event of the FileReader
is asyncrhonous. Which means it's not executed in the natural flow of the program.
To check the final length of the store
variable, you should do this:
var store = [];
document.getElementById('file').onchange = function(){
var file = this.files[0];
var reader = new FileReader();
// Define the body of reader function
reader.onload = function(progressEvent){
// By lines
var lines = this.result.split('\n');
for(var line = 0; line < lines.length; line++){
// Store it in an array
store.push(lines[line]);
}
// Correctly reads the final length of the store variable.
console.log(store.length);
};
reader.readAsText(file);
};
Hope it helps.
Upvotes: 0
Reputation: 1020
FileReader is asynchronous. You either want to use FileReaderSync or do this:
var store = [];
document.getElementById('file').onchange = function() {
var file = this.files[0];
var reader = new FileReader();
// Define the body of reader function
reader.onload = function(progressEvent) {
// By lines
var lines = this.result.split('\n');
for (var line = 0; line < lines.length; line++) {
// Store it in an array
store.push(lines[line]);
}
};
reader.onloadend = function() {
console.log(store.length);
};
// Read the file and store it in the var "store"
reader.readAsText(file);
};
<input type="file" name="file" id="file">
Upvotes: 0
Reputation: 8690
You're setting up an event handler on the onchange property, but you're doing a console.log(store.length) outside, so you will never get the results you expect that way.
The event handler function will be triggered when the value of your element with id "file" changes, so you need to print the length of the store, inside the function, like this:
document.getElementById('file').onchange = function(){
var file = this.files[0];
var reader = new FileReader();
// Define the body of reader function
reader.onload = function(progressEvent){
// By lines
var lines = this.result.split('\n');
for(var line = 0; line < lines.length; line++){
// Store it in an array
store.push(lines[line]);
//console.log(store[line]);
}
console.log(store.length);
};
I would recommend also declaring the store as local to that function, that way you'll always get a brand new array, otherwise you need to manually re-initialize it or empty it before you start adding things to it or on subsequent change events, your "store" array will be filled with everything from the previous changes.
Makes sense?
Upvotes: 1