Ctrl_Alt_Defeat
Ctrl_Alt_Defeat

Reputation: 4009

Getting data from jQuery Deffered function

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?

Upvotes: 0

Views: 48

Answers (1)

Bergi
Bergi

Reputation: 665546

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);
    …
});

Upvotes: 1

Related Questions