jQuery Deferred not working

ajax, javascript, jquery, jquery-deferred

Solution

`Test` is not a deferred object, so it does not have a method `.then()`. `.when()` IS a deferred object hence why it works when you call `.when()`.

Your `$.ajax()` call IS a deferred object, so if you return that as part of your `'Test.start()` method, you can add `.then()` callbacks (see example here), the `.then()` callbacks will be called once the ajax call has been resolved, i.e. has returned its data, however this isn't really the correct use of the deferred object I don't think. The following is more how it is intended to be used I believe:

function searchTwitter(query){
    $.ajax({
            url: "http://search.twitter.com/search.json",
            data: {
                q: query
            },
            dataType: 'jsonp',
            success: function(data){return data;}
        })
        .then(gotresults)
        .then(showDiv)
        .fail(showFailDiv);
};

function gotresults(data) {
    alert(data.max_id);
}

function showDiv() {
    $('<div />').html("Results received").appendTo('body');
}

function showFailDiv() {
    $('<div />').html("Results <b>NOT</b> received").appendTo('body');
}

// Starting can be done with a click:

$("#searchTwitter").click(function(){
   searchTwitter($("#searchName").val()); 
});

// OR a static call:
searchTwitter("ashishnjain");

See it working here

If you want the returned data in for example `showDiv()` change it to `showDiv(data)`.....

Here is another example of how you could create your own deferred object instead of relying on the deferred object of the `.ajax()` call. This is a little closer to your original example - if you want to see it fail for example, change the url to `http://DONTsearch.twitter.com/search.json` example here:

var dfr;

function search(query) {
    $.ajax({
        url: "http://search.twitter.com/search.json",
        data: {
            q: query
        },
        dataType: 'jsonp',
        success: function(data){dfr.resolve(data);},
        error:  function(){dfr.reject();}
    });
}

Test = {
    start: function(){
        dfr = $.Deferred();
        alert("Starting");
        return dfr.promise();        
    }
};


function gotresults(data) {
    alert(data.max_id);
}

function showDiv() {
    $('<div />').html("Results received").appendTo('body');
}

function showFailDiv() {
    $('<div />').html("Results <b>NOT</b> received").appendTo('body');
}

Test.start()
    .then(search('ashishnjain'))
    .then(gotresults)
    .then(showDiv)
    .fail(showFailDiv);

Update to answer the comments:

In your version 11, you are not telling the deferred object of a failure, so it will never call the `.fail()` callback. To rectify this, use the ajax interpretation if the `.fail()` (`error:.......`) to advise the deferred object of a failure `error: drf.reject` - this will run the `.fail()` callback.

As for the reason you are seeing `ShowMoreCode()` run straight away is, the `.then()` calls are callbacks, if you pass it a string representation of a function like: `.then(ShowDiv)` once its turn comes the callback will look for a function with that name. If you pass a call to a function `.then(someMoreCode('Ashish'))` it will run the function. Try it, change `.then(showDiv)` to `.then(showDiv())` you will notice as soon as the code runs, it will show the code from `showDiv()`.

If you change `.then(ShowMoreCode('Ashish'))` to `.then(ShowMoreCode)`, you can access the returned data from the `$.ajax()` call. Like this:

function someMoreCode(name) {
    alert('Hello ' + name.query);
}

Take a look here: working and NOT working `.fail()`

Problem

I am trying out a code as ``` function search(query) { var dfr = $.Deferred(); $.ajax({ url: "http://search.twitter.com/search.json", data: { q: query }, dataType: 'jsonp', success: dfr.resolve }); return dfr.promise(); } Test = { start: function(){ alert("Starting"); } }; function gotresults(data) { alert(data.max_id); } function showDiv() { $('<div />').html("Results received").appendTo('body'); } $.when(search('ashishnjain')) .then(gotresults) .then(showDiv); ``` This works as expected. However when I write it as: ``` Test.start() .then(search('ashishnjain')) .then(gotresults) .then(showDiv); ``` it just alerts "Starting" and terminates.A working example can be found at http://jsfiddle.net/XQFyq/2/. What am I doing wrong?

Original source