1

I am making requests in a loop, trying to accumulate the ID's of the objects given back each time and send to the subsequent request so that they do not get returned a second time. However, the accumulator variable (obviously) is outside of .ajax() success callback, and is empty when I pass it through the data object of the call.

function fill_div(id, count) {
    var rend = "";
    var filler = $('#'+id);
    for(i = 0; i < count; i++) {
        $.ajax({'type':'POST',
                'url':'/ads/render/',
                'dataType':'json',
                'data':"rendered="+rend}).success(function(data){
                    filler.append('<div id="' + data.adid + '"></div>');
                    rend+=data.mid.toString()+",";
                    _fill_ad(data);
                });
    }
}

When I look at the request in chrome's inspector, the variable is there in the post data, but there is no value. I feel like I'm getting something messed up with scoping.

3 Answers 3

3

It looks like the issue here is that you're expecting the returned values to be appended to the rend string in time for the next AJAX call. This isn't going to happen, because making the calls is a synchronous process, but getting the return values is asynchronous. Instead of:

AJAX Post 1 (rend='')
rend += 'id1,'
AJAX Post 2 (rend='id1,')
rend += 'id2,'
AJAX Post 3 (rend='id1,id2,')
// etc

the sequence will most like go something like:

AJAX Post 1 (rend='')
AJAX Post 2 (rend='')
AJAX Post 3 (rend='')
// etc
// ... data is returned, not necessarily in order
rend += 'id2,'
rend += 'id1,'
rend += 'id3,'
// etc

In order to have each subsequent AJAX call aware of what's been previously returned from the server, you'd have to chain the calls, so that the next AJAX call isn't made until the previous call is completed. You could do this with recursion, like this:

function fill_div(id, count) {
    var rend = "";
    var filler = $('#'+id);
    // inner function for recursion
    function doAjaxCall(i) {
        $.ajax({'type':'POST',
            'url':'/ads/render/',
            'dataType':'json',
            'data':{'rendered': rend})
            .success(function(data){
                filler.append('<div id="' + data.adid + '"></div>');
                rend+=data.mid.toString()+",";
                _fill_ad(data);
                // now send the next call
                if (i < count) {
                    doAjaxCall(i+1);
                }
            });
    }
    // kick off the series
    doAjaxCall(0);
}
0

Not sure it's the problem, but shouldn't it be like this for a POST ?

function fill_div(id, count) {
    var rend = "";
    var filler = $('#'+id);
    for(i = 0; i < count; i++) {
        $.ajax({'type':'POST',
                'url':'/ads/render/',
                'dataType':'json',
                'data':{'rendered': rend})
                .success(function(data){
                    filler.append('<div id="' + data.adid + '"></div>');
                    rend+=data.mid.toString()+",";
                    _fill_ad(data);
                });
    }
}

(the difference is that the 'data' is an object and not a string)

1
  • it needs one more } after rend, but it was not an issue
    – Enki
    Commented Jul 27, 2011 at 3:09
0

when the function fill_div executed, there is initialisation on

var rend = "";

and when the POST request constructed,

'data':"rendered="+rend

rend value will be empty

Can you double check the variable name?

:)

1
  • like i understood it, if count is 3, first data will be rendered=, second rendered=[midResult1], and third rendered=[midResult1],[midResult2],.
    – Enki
    Commented Jul 27, 2011 at 3:13

Not the answer you're looking for? Browse other questions tagged or ask your own question.