hud
hud

Reputation: 203

Async AJAX calls overwriting each other

I've got a dashboard page, and am using jQuery to update each graph with a single ajax call.

If it run AJAX with async:false then everything works, but it's obviously slow as the calls are made one after another.

When I run async:true, the queries execute but they all output to the same element and overwrite each other.

How can I ensure that the jQuery selector in the success and error functions remain pointed to their original desintation and do not all point to the final box?

My code:

//update sparklines on dashboard page
        $(".convobox7").each(function() {
            id = $(this).attr('id');
            $("#convobox-7-"+id).prepend("<img src='img/ajax_loader.gif'/>");
            $.ajaxQueue({
                url: '_ajax/getFunnelReport',
                type: "POST",
                dataType: "json",
                async: true,
                data: {funnel:$(this).attr('id'), dimension:'date'},
                timeout: 50000,
                success: function(json) { 
                    var data = json;
                    if (data.success=='true') {
                        $("#convobox-7-"+id).html(data.htmlconv+"<br/><small>Past week</small>");
                        gebo_peity.init();
                    }

                },
                error: function(x, t, m) {
                    $("#convobox-7-"+id).html("");
                }
            })
        });

Note I'm using the ajaxQueue plugin here but the same thing happens without it.

Upvotes: 0

Views: 993

Answers (3)

Beetroot-Beetroot
Beetroot-Beetroot

Reputation: 18078

You need to localise id :

var id = $(this).attr('id');

There may be other things to fix but that one is a certainty.

EDIT

Try this :

$(".convobox7").each(function() {
    var id = $(this).attr('id');
    var $el = $("#convobox-7-"+id).prepend("<img src='img/ajax_loader.gif'/>");
    $.ajaxQueue({
        url: '_ajax/getFunnelReport',
        type: "POST",
        dataType: "json",
        data: {funnel:id, dimension:'date'},
        timeout: 50000,
        success: function(data) {
            if (data.success == 'true') {
                $el.html(data.htmlconv+"<br/><small>Past week</small>");
                gebo_peity.init();
            }
        },
        error: function(x, t, m) {
            $el.html("");
        }
    });
});

Upvotes: 2

AaronLS
AaronLS

Reputation: 38365

This has to do with function closures because you declared the variable outside the success/error function. A better approach is to use the $(this) reference in the error/success functions instead of assigning it outside the handlers.

Edit: In the context of the error/success handler for ajaxQueue, I'm not absolutely certain what $(this) refers to, you may need to navigate to a parent element. I didn't see any definitive documentation offhand. This is one of my biggest pet peeves with javascript documentation, $(this) is sometimes not what you would think it'd be and isn't documented :/

Upvotes: 1

Nick Andriopoulos
Nick Andriopoulos

Reputation: 10643

silly question, but since you already send the element id to the service, is there a reason it cannot send it back? then you can simply use that as a selector, ensuring that you have the item you need.

Upvotes: 0

Related Questions