Jquery: $.when behaves differently depending on number of arguments

javascript, jquery, jquery-deferred

Solution

I don't think you can avoid explicit testing the number of deferred objects. Assuming you want to return the deferred object:

function foo (dfds) {
    if(dfds.length > 1) {
        return $.when.apply(this, dfds);
    }
    else {
        return dfds[0].pipe(function() {
            return [Array.prototype.slice.call(arguments, 0)]
        });
    }
}

You could create a jQuery plugin to wrap this functionality and make it reusable:

(function($) {
    $.when_ = function() {
        if(arguments.length > 1) {
            return $.when.apply(this, arguments);
        }
        else {
            return arguments[0].pipe(function() {
                return [Array.prototype.slice.call(arguments, 0)];
            });
        }
    };
}(jQuery));

You could also override `$.when` but I don't know for sure whether it is used internally or not.

Problem

$.when behaves differently depending on whether one or more Deferred object are passed to it. This behaviour is documented in the docs - but the problem is that it is forcing me to write two different code paths. ``` function foo (dfds) { $.when.apply(this, dfds).done(function() { console.log(arguments); }); } ``` Case I: ``` foo([$.getJSON("http://freegeoip.net/json/8.8.8.8"), $.getJSON("http://freegeoip.net/json/8.8.8.9")]); .... /* Output (what I'd come to expect) */ [Array[3], Array[3]] ``` Case II: ``` foo([$.getJSON("http://freegeoip.net/json/8.8.8.8")]); .... /* Output (the original unwrapped deferred's arguments) */ [Object, "success", Object] ``` Any way to elegantly handle this without resorting to checking the length of `dfd` or the type of `arguments`?

Original source