0

I have a JavaScript function that calls and gets a users cars for there area - it is as below:

function getCars(userId) {
    var cars = $.Deferred();
    var listOfCars = [];

    // Iterate over all areas
    $.when.apply($, $.map(areas, function (area) {
        return $.when(getCarsForArea(area, userId)).then(function (result) {
            $.merge(list, result);
        });
    })).done(function () {
        cars.resolve(list);
    });

    return cars.promise();
}

I then have another deferred that I want to use passing in the result of the function above.

so like

var userCars = $.Deferred();

var result = getCars('1234');  //User 12345 
userCars .resolve(result);

and later I have in a function

$.when(userCars).then(function (carsForUser) {
    console.log(carsForUser);
// rest of method removed for brevity

however in my console I am getting jQuery promise objects logged rather that BMW, Mercedes, etc - i.e - the data from the getCars method.

Is there something I am missing in the way I have wired this up?

Ctrl_Alt_Defeat
  • 3,933
  • 12
  • 66
  • 116

1 Answers1

1
var userCars = $.Deferred();
var result = getCars('1234');  //User 12345 
userCars .resolve(result);

jQuery does no unwrapping of promises in .resolve. Here, result is a promise (the one you returned from getCars()), and therefore userCars will become a promise of a promise. That's why carsForUser will be the result promise in your then callback.

This deferred is totally superflous here. Just do

var userCars = getCars('1234'); // User 12345

and your code will work.


Apart from that, your getCars function is using the deferred antipattern. You should simplify it to

function getCars(userId) {
    // Iterate over all areas
    return $.when.apply($, $.map(areas, function (area) {
        return getCarsForArea(area, userId);
    })).then(Array.prototype.concat.bind([]));
    /* if you're less adventurous, use
    .then(function() {
        var listOfCars = [];
        for (var i=0; i<arguments.length; i++)
            $.merge(listOfCars, arguments[i]);
        return listOfCars;
    }); */
}
getCars('1234').then(function (carsForUser) {
    console.log(carsForUser);
    …
});
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • See "e" at close of `listOfCars` at comment including `$.merge(listOfCarse, arguments[i]);` . What is expected result of `.then(Array.prototype.concat.bind([]));` ? – guest271314 Aug 06 '15 at 03:28
  • @guest271314: Pretty much the same as the commented-out version :-) – Bergi Aug 06 '15 at 03:35
  • `Array.prototype.concat.bind([])` appear to return `function () { [native code] }` ? http://jsfiddle.net/71u0642a/ – guest271314 Aug 06 '15 at 04:05
  • @guest271314: you'll want to *call it* (with multiple arguments that are arrays), that's what `then` does after a `.when`. – Bergi Aug 06 '15 at 04:07