Search code examples
javascriptarraysangularjsloadingsequential

Async loading files with Angular into an object array and keeping their order


I'm not loading scripts, I'm reading XML files into an array of objects. My first [dumb] attempt was something like:

for (var i = 1; i < n; i++) {
    var filePath = "xml/chapter_"+i+".xml";
    $http.get( filePath ).success(function (data) {
        $scope.chaptersData.push (data._chapter); 
    });
}

I quickly figured out this was no good, because the array will be filled in the order the files finished loading, not when they started (a race condition) and the smaller ones will finish first. I can't use the value of 'i' because of course it gets to 'n' long before any of the loading finishes.

After that I thought success(function (data, i) { would work, but it didn't. I'm out of simple ideas, and before I come up with some kind of Rube Goldberg kludge I thought I would ask the wisdom of the Internets if there is a 'right' way to do this.


Solution

  • You can pass i into a function which performs the request.

    for (var i = 1; i < n; i++) {
        getFile(i);
    }
    
    function getFile(index){
        var filePath = "xml/chapter_" + index + ".xml";
        $http.get( filePath ).success(function (data) {
            $scope.chaptersData[index] = data._chapter; 
        });
    }
    

    Within the getFile function, the value of the parameter index will not change as i changes in the outer function. So it will still be at its initial value when the success function executes and can be used for populating the array.