Using $.when with Ajax requisitions - javascript

I want to execute some $.ajax() requisitions in a certain order, so I tried to use $.when like this:(just for testing)
$.when.apply(null,[ajaxRequisition1(),ajaxRequisition2()] ).then(function () {
console.log("Completed all requests.");
});
But it shoots the message on the console before the requisitions are done. Any suggestions?
Thanks
EDIT
Here are one of my requisitions. I'll post one, but the others are very similar, changing only some parameters.
code:
function ajaxRequisition1(){
$.ajax({
type:'GET',
crossDomain:true,
url:'http://www.myurl.com.br/api/my_php.php?callbackplat=?',
dataType:'jsonp',
data: {currency: $('#cur').val()},
beforeSend: function(){
$('#loading').css("display","block");
$('table[name=tb_latam]').css("opacity","0.01");
}
}).done(function(data){
console.log(data);
//HERE I BUILD A TABLE USING THE DATA RECEIVED.
$('#loading').css("display","none");
$('table[name=tb_latam]').css("opacity","1");
$('#tb_latam').append('<tr> <td data-nome="A-ACTIVE" class="column_st">'+'Active'+
'</td><td class="c_qtdA column_qtd">'+data.lat_qtdA+
'</td><td id="a2"class="a">'+data.lat_active+
'</td><td>'+data.lat_p_active+'</td></tr>');
$('#tb_latam').append('<tr> <td data-nome="I-INACTIVE" class="column_st">'+'Inactive'+
'</td><td class="c_qtdI column_qtd">'+data.lat_qtdI+
'</td><td class="i">'+data.lat_inactive+
'</td><td>'+data.lat_p_inactive+'</td></tr>');
$('#tb_latam').append('<tr> <td data-nome="R-REPLACED" class="column_st">'+'Replaced'+
'</td><td class="c_qtdR column_qtd">'+data.lat_qtdR+
'</td><td class="r">'+data.lat_replaced+
'</td><td>'+' - '+'</td></tr>');
})
.fail(function(data, textStatus, errorThrown){
alert("ERROR!.");
console.log(data);
console.log(textStatus);
console.log(errorThrown);
});
return false;
}

jQuery $.when() accepts deferred objects. While your ajaxRequisition returns a non deferred, $.when() will then return a resolved promise.
Try to change your code,
function ajaxRequisition1 () {
return $.ajax({
...
});
}
function ajaxRequisition2 () {
return $.ajax({
...
});
}
$.when.apply(null, [ajaxRequisition1(),ajaxRequisition2()]).done(function () {
console.log("Completed all requests.");
});

I believe you need to use .done(...).
Check this to learn the differences.
edit
As per the docs of jquery, if you pass NOT-a-promise to the .when(...) method, the .then(...) will get called automatically and treat the arguments you passed to .when(...) as already resolved promises, and also pass them to the .then(...)
So, the array you're passing have to be promises so that the .when(...) gets called at the correct time.
If a single argument is passed to jQuery.when() and it is not a Deferred or a Promise, it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately.
Check docs.
edit 2
I thought your ajaxRequisitions methods were already working. Here's the example from the docs to the .when(...) function
$.when( $.ajax( "test.aspx" ) ).then(function(
data, textStatus, jqXHR ) {
alert( jqXHR.status ); // Alerts 200
});
You need to update it so you can add the .apply(...), and have your ajaxRequisition... Methods return the Ajax call you need in each one.

Related

Why doesn't changing the href value using $().prop() work within a $.getJSON call?

I am trying to change the href value from within a getJSON call. The following works outside the call but not inside. Any ideas?
$("#tweetButton").prop("href", "https://twitter.com/intent/tweet?text=test&url=%20&hashtags=quotes");
HTML:
<div id="quote">
<div id="quoteText">
Test
</div>
</br>
<a id="tweetButton" href="https://twitter.com/intent/tweet?text=&url=%20&hashtags=quotes" class="twitter-share-button">Tweet</a>
<button id="btnNewQuote">New Quote</button>
</div>
jQuery:
$(document).ready(function() {
$.ajaxSetup({ cache: false });
$.getJSON("http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&callback=", function(a) {
$("#tweetButton").prop("href", "https://twitter.com/intent/tweet?text=test&url=%20&hashtags=quotes");
$("#quoteText").html(a[0].content + "<p>— " + a[0].title + "</p>");
// $("#tweetButton").attr("href", "https://twitter.com/intent/tweet?text=" + encodeURI(a[0].content) + encodeURI(" -") + a[0].title + "&url=%20&hashtags=quotes");
});
$("#btnNewQuote").click(function(){
$.getJSON("http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&callback=", function(a) {
$("#quoteText").html(a[0].content + "<p>— " + a[0].title + "</p>");
$("#tweetButton").prop("href", "https://twitter.com/intent/tweet?text=test&url=%20&hashtags=quotes");
});
});
});
href isn't a property, it's an attribute. Use .attr() rather than .prop().
In the jQuery docs for .getJSON(), it says:
if the JSON file contains a syntax error, the request will usually fail silently.
So, if the returned result is not valid JSON, your success function won't run and you won't see any other indicator that something went wrong.
I suspect this is what your issue is due to including &callback= in your urls. For services that understand JSONP (no, that isn't a typo) calls, this would wrap your returned JSON object in parentheses because you essentially asked for the JSON object to be wrapped in a function call without giving a name for the function. This would result in the invalid syntax.
You can't just remove callback because the whole point of JSONP is to enable cross domain requests (which you are attempting). jQuery needs to know that's what you're doing and $.getJSON() isn't setup to handle that sort of thing.
You'll need to arrange your code like this:
$.ajax({
type:"GET",
url: "//quotesondesign.com/wp-json/posts",
jsonp: "callback",
crossDomain: true,
data: {
filter: {
orderby: "rand",
posts_per_page: 1
}
},
success: function( response ) {
console.log( response ); // javascript object representing response
},
error: function() {
console.log('error');
}
});
This ended up being a CodePen issue. I tested on JSBin, using both getJSON and ajax directly and it worked fine!

Jquery ajax call data not binding [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
I have a function which returns html code based on pulled json data from the controller. I am trying to append the jquery ajax call result to a div after completing the ajax operation.
The problem is there are 100 records in json and pulling them take little time. Data is not binding to the div. But when I add an alert it shows the data. I think the background time to display alert and clicking on ok is setting the ajax resulted data. Do we have any good option to bind data or to bind data only after data is completely loaded? I tried with complete function but it didnt work.
function queryOrdersExtraRow() {
var Details;
$.ajax({
url: "../MoreDetails/GetJsonDetails",
type: 'Get',
dataType: 'json',
data:{Id:138},
cache: false,
contentType: 'application/json',
success: function (result) {
Details = '<table class="extra">' +
'<tr><th>Name#</th><td>' + result.name + '</td></tr>' +
'<tr><th>Address Type</th><td>' + result.address + '</td></tr>'+
'<tr><th>Phone:</th><td>' + result.phone + '</td></tr>' +
'</table>';
return Details;
},
error: function (error, textStatus, errorThrown) {
reportFriendlyAjaxError(error, textStatus, errorThrown);
},
complete: function () {
}
});
//alert(Details);
return Details;
//Bind data here
}
Instead of using return, call your binding function right within the success.

$.getJSON with in a foreach Loop over all input fields

i have a quick question. I want to iterate over all checked checkboxes and parse the json files for the checked ones.
Here is my problem: The $().each function is synchronous and the $.getJSON() function is asynchronous. So i know i would have to pause the exectuion of the each() loop until the JSON File is parsed. How can i pause the loop? Or any other ideas solving this problem?
Thank you very much.
$("input:checkbox[name=check]:checked").each(function()
{
$.getJSON( $(this).val(), function( data ) {
//Do smth.
//Pause the each loop?
}).error(function(jqXhr, textStatus, error) {
alert("ERROR: " + textStatus + ", " + error);
});
});
alert("foo"); //<-- gets executed before all json files are parsed.
If you want to make the AJAX request synchronouse, pass async config as false.
$.ajax({
dataType: "json",
url: 'your URL',
async: false,
success: success
});
Documentation

Chaining AJAX handlers with jQuery Deferred

I just can't seem to get a handle on jQuery's $.Deferred handling of AJAX calls.
What I want to do is execute three AJAX calls, each of which performs some processing on the returned data. The success call of the third AJAX call requires that the processing from the first two calls be complete, but the order of the first two calls does not matter.
Here is my code, and a jsFiddle:
var firstAjax = $.getJSON('/echo/json/')
.done(
function(data, textStatus, jqXHR){
//do some initialization here based on the data
alert(1);
return jqXHR.promise();
}
);
var secondAjax = $.getJSON('/echo/json/')
.done(
function(data, textStatus, jqXHR){
//do some initialization here based on the data
alert(2);
return jqXHR.promise();
}
);
$.when(firstAjax, secondAjax)
.done(
$.getJSON('/echo/json/')
.done(
function(data, textStatus, jqXHR){
//do some initialization here that relies on the initialization of the first and second calls being complete
alert(3);
}
)
);
Sometimes, but not always, "3" is alerted before "1" and "2". I have no problem with performing the third AJAX call immediately but its done handler needs to execute last.
you can do
var firstAjax = $.getJSON('/echo/json/').done(
function(data, textStatus, jqXHR){
//do some initialization here based on the data
alert(1);
return jqXHR.promise();
}
);
var secondAjax = $.getJSON('/echo/json/')
.done(
function(data, textStatus, jqXHR){
//do some initialization here based on the data
alert(2);
return jqXHR.promise();
}
);
$.when(firstAjax, secondAjax)
.done(function(){
$.getJSON('/echo/json/')
.done(
function(data, textStatus, jqXHR){
//do some initialization here that relies on the initialization of the first and second calls being complete
alert(3);
}
)
});
you miss the "function(){" on this line $.when(firstAjax, secondAjax).done(function(){
http://jsfiddle.net/ACBJs/1/

How to create DOM elements on $.Ajax() Success using jquery ?

i'm creating a dynamic list of checkbox on $.ajax :
function load() {
$.ajax({
type: "POST",
url: "*************",
data: "************",
dataType: "json",
contentType: "application/json; charset=utf-8",
error: function (x, e) { alert(e.responseText); },
success: function (objTrendList) {
$.each(objTrendList, function (index, value) {
// append the checkbox panels to tool div
$('#tools').append('<input type="checkbox" id="checkbox_' +
value.LngTrendID + '" checked="checked" value="0" /> <div
style="display:inline;">' + value.StrTrendName + '</div><br />');
});
}
});
}
$(document).ready(function () {
load();
console.log($('#tools :checkbox')); // i know I don't get any thing here
because the this line is called before the ajax function
});
i know I don't get any thing with the console.log line because the this line is called before the ajax function
Question How can i load the ajax function first i though when i do $(document).ready() it will run last
Thanks
Return the ajax call and use the already built in deferred object in $.ajax :
function load() {
return $.ajax({
type: "POST",
url: "*************",
data: "************",
dataType: "json",
contentType: "application/json; charset=utf-8",
error: function (x, e) { alert(e.responseText); },
success: function (objTrendList) {
$.each(objTrendList, function (index, value) {
// append the checkbox panels to tool div
$('#tools').append('<input type="checkbox" id="checkbox_' +
value.LngTrendID + '" checked="checked" value="0" /> <div
style="display:inline;">' + value.StrTrendName + '</div><br />');
});
}
});
}
$(document).ready(function () {
load().done(function() {
console.log($('#tools :checkbox')); // i know I don't get any thing here
});
});
The reason you don't have anything in the log is because $.ajax is asynchronous (the first 'A' in AJAX stands for 'Asynchronous'). Meaning that when you call your load() function, it fires off the $.ajax call, but does not wait for the $.ajax call to return before load() returns (this is why you must specify a success and error function so it know what to do when it actually does return).
We can look at a timeline of how your code gets executed:
load()
$.ajax()
return (null)
console.log()
(some indeterminate time later) success()
$.ajax() returns a type of object that knows when it has returned from it's call. Therefore you can call .done() on the object and execute code in that function that will wait until after the success() has run.
therefore if you return the $.ajax call you will be able to call .done() and do things with your newly-added inputs.
function load() {
return $.ajax({...});
}
$(document).ready(function () {
load().done(function(){
console.log($('#tools :checkbox'));
});
});

Categories

Resources