jQuery.when understanding

JqueryAjaxJquery Deferred

Jquery Problem Overview


I am trying to use the jQuery.when to fire two ajax requests and then call some function after the two requests have completed. Here's my code:

var count = 0;
var dfr;

var showData = function(data) {
    dfr.resolve();
    alert(count);
   // Do something with my data data received
};

var method1 = function() {
    dfr = $.Deferred();

    return $.ajax('localhost/MyDataService/DataMethod_ReturnsData', {
	    dataType: "jsonp",
	    jsonp: "$callback",
	    success: showData
    });
};

var method2 = function() {
    return $.ajax('localhost/MyDataService/DataMethod_ReturnsCount', {
	    dataType: "jsonp",
	    jsonp: "$callback",
	    success: function(data) {
	        count = data.d.__count;
	    }
    });
};

$.when(method1(), method2())
	.then(showData());

However this is not working as expected. Ajax call in method1 will return data which is to be used in showData() and Ajax call in method2 will return count which is to be assigned to var count and later used in showData().

But when I fire the above code, method1 gets called and then method2 and then showData leaving the data in showData as 'undefined'. How can I achieve this via $.when which as far as I know proceeds only when both functions returning $.promise are executed. I want that both the ajax calls should be called in parallel and later results be displayed based on results from both calls.

Jquery Solutions


Solution 1 - Jquery

function showData(data1, data2) {
    alert(data1[0].max_id);
    alert(data2[0].max_id);
}

function method1() {
    return $.ajax("http://search.twitter.com/search.json", {
        data: {
            q: 'ashishnjain'
        },
        dataType: 'jsonp'
    });
}

function method2() {
    return $.ajax("http://search.twitter.com/search.json", {
        data: {
            q: 'ashishnjain'
        },
        dataType: 'jsonp'
    });
}

$.when(method1(), method2()).then(showData);​

Here's a working jsFiddle

Solution 2 - Jquery

The problem is that you're passing showData() to then(), not showData. You should pass a reference to a function to .then():

$.when(method1(), method2())
    .then(showData);

or

$.when(method1(), method2())
    .then(function () {
    	showData();
    });
   
Edit

I've put together a working demo. Part of the problem (at least in the code fragment you posted) was that there was no callback function named $callback. Part of the problem was the $ in the callback name '$callback'.

So, remove the jsonp: '$callback' ajax option, so that jQuery defaults to a callback function named callback, and define a function with that name, and it all works.

Solution 3 - Jquery

I have little bit modified your code and made simpler to understand... i haven't test it please try it

var count = 0;
function countResponse(data) {
	count++;
	if(count==2)
	{
		// Do something after getting responce from both ajax request
	}
};

var method1 = function() {
    return $.ajax('localhost/MyDataService/DataMethod_ReturnsData', {
        dataType: "jsonp",
        jsonp: "$callback",
        success: function(data) {
        	countResponse(data)
        }
    });
};

var method2 = function() {
    return $.ajax('localhost/MyDataService/DataMethod_ReturnsCount', {
        dataType: "jsonp",
        jsonp: "$callback",
        success: function(data) {
        	countResponse(data)
        }
    });
};

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAshishView Question on Stackoverflow
Solution 1 - JqueryGuillaume86View Answer on Stackoverflow
Solution 2 - JqueryMatt BallView Answer on Stackoverflow
Solution 3 - JqueryHaresh VidjaView Answer on Stackoverflow