G.One
G.One

Reputation: 209

Array.push not updating an array variable

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

Answers (3)

rdleal
rdleal

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

trevorade
trevorade

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

Deleteman
Deleteman

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

Related Questions