Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chaining ajax requests with jQuery's deferred

I have a web app which must call the server multiple times. So far, I had a long nested callback chain; but I would like to use jQuery's when,then etc. functionality. However, I can't seem to get stuff running again after using a then.

$
.when ($.get('pages/run-tool.html'))
.then (function (args)
{
    // This works fine
    alert(args);
    $('#content').replaceWith (args);
    $('#progress-bar').progressbar ({value: 0});
})
.then ($.get('pages/test.html'))
.done (function(args)
{
    // This prints the same as the last call
    alert (args);
});

What am I doing wrong? I guess its some scoping issue, as I can see the second get call being executed. Using two different args variables does not help as the argument passed to the done function is still the first get request.

like image 512
Anteru Avatar asked Nov 08 '11 10:11

Anteru


2 Answers

As an update:

With modern jquery (1.8+) you don't need the preliminary when because get returns a Deferred Promise.

Also, pipe is deprecated. Use then instead. Just be sure to return the result of the new get which becomes the Promise attached to by subsequent then/*done*/fail calls.

So:

$.get('pages/run-tool.html')
.then (function (args) { // this will run if the above .get succeeds
    // This works fine
    alert(args);
    $('#content').replaceWith (args);
    $('#progress-bar').progressbar ({value: 0});
})
.then (function() { // this will run after the above then-handler (assuming it ran)
    return $.get('pages/test.html'); // the return value creates a new Deferred object
})
.done (function(args) { // this will run after the second .get succeeds (assuming it ran)
    alert (args); 
});
like image 57
cdr Avatar answered Oct 13 '22 04:10

cdr


All three callbacks (the two with then and the one with done) are applied to the same request – the original when call. This is because then returns the same Deferred object, rather than a new one, so that you can add multiple event handlers.

You need to use pipe instead.

$
.when ($.get('pages/run-tool.html'))
.then (function (args)
{
    // This works fine
    alert(args);
    $('#content').replaceWith (args);
    $('#progress-bar').progressbar ({value: 0});
})
.pipe (function() { 
    return $.get('pages/test.html'); // the return value creates a new Deferred object
})
.done (function(args)
{
    alert (args);
});
like image 25
lonesomeday Avatar answered Oct 13 '22 03:10

lonesomeday