jQuery .when troubleshooting with variable number of arguments

Alex picture Alex · Mar 26, 2012 · Viewed 10.9k times · Source

I'm having an issue with using jQuery.when() to wait for multiple ajax requests to finish before calling another function.

Each ajax request will get JSON data, and looks something like this:

   function loadData(arg){
        var ajaxCall = $.ajax(
            URL // depends on arg
        )
       .error( .... );
       return ajaxCall;
   }

When the request is called, the return value (ajaxCall) is added to a list called ajaxRequests.

    ajaxRequests = [];
    ajaxREquests.push(loadData(arg))

When all the requests have been made, I'm trying to pass ajaxRequests to $.when in order to wait for all requests to complete.

        var defer = $.when.apply($, ajaxRequests);
        defer.done(function(args){
            for (var i=0; i<args.length; i++){
                inst.loadData($.parseJSON(args[i].responseText));
            }
            inst.draw();
        });

inst is an object that loads and draws graphs based on JSON data.

The problem is that it doesn't seem to be actually waiting for the requests to finish - args[i] is an object, but responseText is undefined when the code runs. If I save args[i] and access it later from the console, it works.

I suspect the problem is related to using .when with an arbitrary number of arguments, as all the examples I've seen on the web give it a pre-defined argument list.

I'm not sure if using apply was the right idea or not, but either way it doesn't work properly and behaves erratically (browser-dependent).

Any help would be greatly appreciated.

Please let me know if more information is required.
I'm using jQuery 1.5

Answer

Andy Corman picture Andy Corman · Apr 29, 2013

Although Alex did indeed provide a solution to his problem, I found following it a bit difficult. I had an issue similar to his that I solved, and I wanted to share my solution for anyone else who needs to process a variable number of ajax requests.

// Array of requests
var requests = Array();
requests.push($.get('responsePage.php?data=foo'));
requests.push($.get('responsePage.php?data=bar'));

var defer = $.when.apply($, requests);
defer.done(function(){

    // This is executed only after every ajax request has been completed

    $.each(arguments, function(index, responseData){
        // "responseData" will contain an array of response information for each specific request
    });

});