0

I need to loop thru div's and load them using the promise pattern but apparently only the data from the last call gets displayed.

Here is my code

$('div[class=ceTable]').each(function () {
    var position = $(this).position();
    gridID = $(this).attr('id')
    tableID = $(this).attr("data-tableid")
    docId = $(this).attr("data-docid")
    headerFound = $(this).data("headerFound")
    headerArray = $(this).data("headerArray")
    columnCount = $(this).data("columnCount")

    $.ajax({
        type: "GET",
        dataType: "json",
        url: "ajaxGetTableData",
        data: {
            'docID': docId,
            'tableID': tableID
        },

        beforeSend: function () {
            $('#' + gridID).block({
                css: {
                    border: 'none',
                    padding: '15px',
                    backgroundColor: '#36a9e1',
                        '-webkit-border-radius': '10px',
                        '-moz-border-radius': '10px',
                    opacity: 5,
                    color: '#fff'
                },
                message: 'Loading Grid'
            });
        }

    }).done(function (data) {
        console.log(data, "ajaxGetTableData")
        ceFeature.generateGridFromJSONObject({
            tabledata: data,
            columnCount: columnCount,
            gridID: gridID,
            headerArray: headerArray,
            headerFound: headerFound
        })
        $('#' + gridID).unblock();
    })
Tushar Gupta - curioustushar
  • 58,085
  • 24
  • 103
  • 107
allthenutsandbolts
  • 1,513
  • 1
  • 13
  • 34

2 Answers2

3

Your variables are implicitly global (as you forgot the var keyword) so each iteration will overwrite the previous values. The async callbacks will only access the last one then - the typical creating functions in a loop problem.

To fix this, make the variables local to the function (the each callback) so that it makes the success callback a closure with the respective variables in its scope:

$('div[class=ceTable]').each(function () {
    var position = $(this).position(),
        gridID = $(this).attr('id'),
        tableID = $(this).attr("data-tableid"),
        docId = $(this).attr("data-docid"),
        headerFound = $(this).data("headerFound"),
        headerArray = $(this).data("headerArray"),
        columnCount = $(this).data("columnCount");
    …
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 1
    Wow i didn't see it and didn't even think about it! Thx! – A. Wolff Sep 18 '13 at 16:44
  • Thanks for all the suggestions. I just made a function out of the deferred call and it worked. Read about creating closures in functions on the MDN site, its not a recommended approach. – allthenutsandbolts Sep 18 '13 at 18:48
  • Closures *are* the recommended (and only possible) approach. The warning at MDN just states that you can abuse them. In this case you already have a closure anyway by using `$().each` - you should not use two closures as in A.Wolff's answer. – Bergi Sep 18 '13 at 18:49
2

Using a closure:

$('div[class=ceTable]').each(function () {
    var position = $(this).position();    
    gridID = $(this).attr('id')
    tableID = $(this).attr("data-tableid")
    docId = $(this).attr("data-docid")
    headerFound = $(this).data("headerFound")
    headerArray = $(this).data("headerArray")
    columnCount = $(this).data("columnCount")
    (function (columnCount, gridID, headerArray, headerFound) {    
        $.ajax().done();
    }(columnCount, gridID, headerArray, headerFound));
});
A. Wolff
  • 74,033
  • 9
  • 94
  • 155