Search code examples
javascriptxmlhttprequest

Javascript array length when reading a file


I am loading some files form my server via XMLHttpRequest. The loaded files should then be pushed onto an Array object so that I can process them. Here is my code:

var fileList = [];

angular.forEach(images, function(image, key) {

let xhr = new XMLHttpRequest();

xhr.open('GET', '/img/listings/' + image.dir + '/' + image.name, true);
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xhr.responseType = 'blob';

xhr.send();

xhr.onload = function() {
    if (xhr.status != 200) { // analyze HTTP status of the response
        alert(`Error ${xhr.status}: ${xhr.statusText}`); // e.g. 404: Not Found

    } else {
        var blob = new File([this.response], {type: 'image/png'}); 
        fileList[0] = blob; 
    }

};

console.log(fileList);
console.log(fileList.length);

The result of the console log is:

[]
0: File {name: "[object Object]", lastModified: 1569449982337, lastModifiedDate: Wed Sep 25 2019 23:19:42 GMT+0100 (British Summer Time), webkitRelativePath: "", size: 77928, …}
length: 1
__proto__: Array(0)

But the length is 0. Why is the length 0 when it has content.


Solution

  • There are few little things happening.

    First, change this code:

    xhr.onload = function() {
        if (xhr.status != 200) { // analyze HTTP status of the response
            alert(`Error ${xhr.status}: ${xhr.statusText}`); // e.g. 404: Not Found
    
        } else {
            var blob = new File([this.response], {type: 'image/png'}); 
            fileList[0] = blob; 
        }
    };
    console.log(fileList);
    console.log(fileList.length);
    

    to

    xhr.onload = function() {
        if (xhr.status != 200) { // analyze HTTP status of the response
            alert(`Error ${xhr.status}: ${xhr.statusText}`); // e.g. 404: Not Found
    
        } else {
            var blob = new File([this.response], {type: 'image/png'}); 
            // You wanted to add to the array.
            // Using fileList[0] will overwrite the 0 element/object
            fileList.push(blob);
        }
       //console.log(fileList);
       console.log(fileList.length);
    };
    

    And the reason why?

    Placing the console.log outside of the AJAX will not work as the AJAX will work on a different thread in the background but the console.log call will be run on main thread. See How do I return the response from an asynchronous call? for a lot more detail.

    The other thing you are doing is overwriting your 0 index element of fileList with the fileList[0] = blob;. You will need to change that to fileList.push(blob); to add the object to the array.