elementzero23
elementzero23

Reputation: 1429

Fill array by multiple AJAX requests, then pass array to another function

(My solution below)

I have several HTML elements with class .canvas-background of which information is stored in the database. I want to get the information of each element and process it via JavaScript. But somehow I can't pass the response of the AJAX request to another function. Here is what I've tried:

function initTabs() {
    var tabs = loadTabInformation();
    console.log(tabs); // (1)
    // do something else
}

function loadTabInformation() {
    var requests = new Array();
    var tabs = new Object();
    var counter = 0;
    $(".canvas-background").each(function () {
        var tabNumber = $(this).data("tab-number");
        var request = $.ajax({
            type: 'POST',
            url: '../db/GetTabInformation.ashx',
            data: String(tabNumber),
            dataType: 'json',
            contentType: 'text/plain; charset-utf-8'
        })
        .done(function (response) {
            tabs[counter++] = response;
        }).fail(function (jqXHR, textStatus, errorThrown) {
            console.log("request error in loadTabInformation()");
            console.log(textStatus);
            console.log(errorThrown);
        });
        requests.push(request);
    });
    $.when.apply($, requests).done(function () {
        console.log(tabs); // (2)
        return tabs;
    });
}

At (1) I get undefined, but at (2) everything seems to be alright.

THE SOLUTION:

Thanks to the answer and the link in the comment @Kim Hoang provided I got this working. The clue seemed to put the done() function in the calling function, that is initTabs() in my case. Another thing I got wrong was to try to do the logic that should be executed after the AJAX requests had finished outside the done callback function. They must be inside (makes sense, if you think about it). And a lot of conosle output helped, to see what function returns what kind of object.

function initTabs() {
    var tabInfoRequest = loadTabInfo();
    tabInfoRequest[0].done(function() {
        var results = (tabInfoRequest[1].length > 1) ? $.map(arguments, function(a) { return a[0]; }) : [arguments[0]];
        for (var i = 0; i < results.length; i++) {
            // do something with results[i]
        }
    });
}

function loadTabInfo() {
    var tabNumbers = new Array();
    $(".canvas-background").each(function () {
        tabNumbers.push($(this).data("tab-number"));
    });
    var requests = $.map(tabNumbers, function (current) {
        return $.ajax({
            type: 'POST',
            url: '../db/GetTabInformation.ashx',
            data: String(current),
            dataType: 'json',
            contentType: 'text/plain; charset-utf-8'
        });
    });
    var resultObject = new Object();
    resultObject[0] = $.when.apply($, requests);
    resultObject[1] = requests;
    return resultObject;
}

Note: I only did the resultObject-thing because I needed the array requests in the initTabs() function.

Thank you very much for helping me!

Upvotes: 0

Views: 458

Answers (1)

Kim Hoang
Kim Hoang

Reputation: 1368

You do not return anything in loadTabInformation, so of course you will get undefined. You should do it like this:

function loadTabInformation() {
    ...
    return $.when.apply($, requests);
}

function initTabs() {
    loadTabInformation().done(function (tabs) {
        console.log(tabs); // (1)
        // do something else
    });    
}

Upvotes: 4

Related Questions