I am looking to fire off several jQuery AJAX requests in quick succession, so the response will not come before the next request. However, I do want to handle each one of these responses with the success function.
With the following code, the first two responses will be ignored and only the last one will respond.
$('#button').click(function() {
var num = 3;
for(var i=0;i<num;i++)
ajaxCall(i);
}
function ajaxCall(data){
$.ajax({
url: '/echo/html/',
success: function(msg) {
alert(msg);
}
});
}
However I am trying to make it so that all three alerts would show up. It seems that each time the ajaxCall function is called it uses the same 'object' as it did the previous time instead of instantiating a new one, which is what I want to do.
Try this (using Deferred Object)
$('#button').click(function() {
var num = 3;
for(var i=0;i<num;i++) {
ajaxCall(i).done(function(data)
{
alert(data)
}
);
}
});
function ajaxCall(data){
return $.ajax({
url: '/echo/html/'
});
}
Related
I am using below code
var lockonscreens = 1;
jQuery(document).ready(function(e) {
var noOfSelection = 0;
if(lockonscreens == 0){
// some stuff
}
if(lockonscreens == 1){
// some stuff
}
});
function ajaxcall(){
jQuery.ajax({
url:
type:
data:
async: false,
success: function(data){
lockonscreens = data;
}
});
}
jQuery("#").click(function(){
ajaxcall();
});
I am using above code to get some data through ajax and set it to variable and depending on that variable a click event code may happen.
But on ajax call the global variable value doesn't get changed.
It remains the same even if the data changes in ajax.
Can anyone let me know what is the issue and how to correct it?
Remember that ajax is asynchronous, so if you call ajaxCall() and next an other function, ajax start the call to server and the function end.
When the server respond, the code after success: is executed.
Make sure you call the function in the success: function
Why is it that whenever I put an ajax inside a for loop, it doesn't synchronize well?
like for example, my code is:
function addToUserGroupList() {
_root.qDomId('js-assignGroupArrBtn').disabled = true
for (var i = 0; i < selectedIds.length; i++) {
$.ajax({
type: "POST",
url: 'groupManage.ashx',
dataType: 'text',
data: 'type=getInfo&groupId=' + selectedIds[i],
success: function (result) {
if (result != '') {
this.groupName = result.split('&')[0];
this.groupNotes = result.split('&')[2];
userGroupList.push({ 'uid': parseInt(selectedIds[i]),
'name': this.groupName,
'adminStr': this.groupNotes
});
_root.userListObj.gourpInst.gourpTB(userGroupList);
}
},
error: function (XMLHttpRequest, status, errorThrown) {
alert('failed to add to user\'s group.');
}
});
}
_root.qDomId('js-assignGroupArrBtn').disabled = false;
selectedIds = [];
}
Why is that it calls out selectedIds = []; first before the Ajax Query?
Is it possible to let the ajax queries be finished before proceding to selectedIds = [];? Because it clears the array right before it's finished doing the stuffs. :/
First off, you really need to understand how an Ajax call is Asynchronous (that's what the "A" in Ajax stands for). That means that calling $.ajax() only starts the ajax call (it sends the request to the server) and the rest of your code happily continues running. Sometimes LATER after the rest of your code has executed, the success or error callback handler is called when the response comes back from the server. This is NOT sequential programming and must be approached differently.
The #1 thing this means is that ANYTHING that you want to have happen after the ajax call MUST be in the success or error handler or called from there. Code located right after the ajax call will be run long before the ajax call completes.
So, there are different ways to structure your code to work with this asynchronous concept. If you only want one asynchronous ajax call in flight at a time, you have to do this restructuring and can't use a simple for loop. Instead, you can create an index variable and in the completion function, increment the index and kick off the next iteration. Here's one way to code it:
function addToUserGroupList() {
_root.qDomId('js-assignGroupArrBtn').disabled = true
var i = 0;
function next() {
if (i < selectIds.length) {
$.ajax({
type: "POST",
url: 'groupManage.ashx',
dataType: 'text',
data: 'type=getInfo&groupId=' + selectedIds[i],
success: function (result) {
i++;
if (result != '') {
this.groupName = result.split('&')[0];
this.groupNotes = result.split('&')[2];
userGroupList.push({ 'uid': parseInt(selectedIds[i]),
'name': this.groupName,
'adminStr': this.groupNotes
});
_root.userListObj.gourpInst.gourpTB(userGroupList);
}
next();
},
error: function (XMLHttpRequest, status, errorThrown) {
alert('failed to add to user\'s group.');
}
});
} else {
// last one done
_root.qDomId('js-assignGroupArrBtn').disabled = false;
selectedIds = [];
}
}
// kick off the first one
next();
}
I'm using jQuery to send an AJAX request, retrieving data from a server.
That data is then appended to an element. This should happen 5 times, but it will always happen randomly either 3, 4, or 5 times. Basically, sometimes the loop will skip the AJAX request, but the majority of the time it catches it. How do I make sure it completes the request five times every time? and what is the reason behind this random behavior of skipping AJAX request?(side note. I've checked the request errors, but it never alerted of a request failure)
Here's my JS:
while (counter < 6) {
$.ajax({
url:'http://whisperingforest.org/js/getQuote.php',
async: false,
dataType: 'jsonp',
success:function(data){
$('.quoteList').append('<li>' + data +'</li>');
totalQuotes++;
}
});
counter++;
}
P.s. this happens on a button press.
Don't do it synchronously. Use the callback. Here is a demo for you: http://jsfiddle.net/y45Lfupw/4/
<ul class="quoteList"></ul>
<input type="button" onclick="getData();" value="Go Get It!">
<script>
var counter = 0;
window.getData=function()
{
/* This IF block has nothing to do with the OP. It just resets everything so the demo can be ran more than once. */
if (counter===5) {
$('.quoteList').empty();
counter = 0;
}
$.ajax({
/* The whisperingforest.org URL is not longer valid, I found a new one that is similar... */
url:'http://quotes.stormconsultancy.co.uk/random.json',
async: true,
dataType: 'jsonp',
success:function(data){
$('.quoteList').append('<li>' + data.quote +'</li>');
counter++;
if (counter < 5) getData();
}
});
}
</script>
Setting async to false blocks the main thread (responsible for
executing JavaScript, rendering the screen, etc) and waits for the XHR
to complete.
This is almost always a terrible idea. Users don't like unresponsive
UIs. (https://stackoverflow.com/a/20209180/3112803)
Just search stackoverflow for ajax async: false and you will find MANY good explanations on this. Everyone will discourage you from using async:false. Here's is a great explanation: https://stackoverflow.com/a/14220323/3112803
Very interesting methods provided by jQuery when you are executing loops of asyncroniouse request and detect all ajax request completed or not. It is possible by using
var users=["a","b","c","d","e","f","g","h"];
var async_request=[];
var responses=[];
for(i in users)
{
// you can push any aysnc method handler
async_request.push($.ajax({
url:'', // your url
method:'post', // method GET or POST
data:{user_name: users[i]},
success: function(data){
console.log('success of ajax response')
responses.push(data);
}
}));
}
$.when.apply(null, async_request).done( function(){
// all done
console.log('all request completed')
console.log(responses);
});
Here $.when provides a way to execute callback functions based on zero
or more objects, usually Deferred objects that represent asynchronous
events.
apply() converts array elements as different arguments in
function
$.done is call function after all async. request are
completed.
You can use ES6 async/await Promises like this
function fromServer(){
return new Promise((resolve, reject) => {
$.ajax({
url:'http://whisperingforest.org/js/getQuote.php',
async: false,
dataType: 'jsonp',
success:function(data){
resolve(data)
}
});
})
}
var totalQuotes = 0;
async function domManipulation(){
while (counter < 6) {
var data = await fromServer();
$('.quoteList').append('<li>' + data +'</li>');
totalQuotes++;
}
}
domManipulation()
JSFIDDLE
I have a problem passing data from a JQuery ajax call back to the calling location. The code in question is below:
jQuery("#button").click(function()
{
for(var i = 0;i < data.length; i++)
{
result = updateUser(data[i]); //result is not populated..
alert(result); //prints 'undefined'
}
});
function updateUser(user_id)
{
jQuery.ajax({
url:"/users/update/"+user_id,
type:"GET",
async: false,
success: (function(data){
//if I alert "data" here it shows up correctly
//but if i try to return it like below
//it does not get passed correctly
return data;
})
});
Any pointers are greatly appreciated
You cannot return value from an AJAX success handler like that. AJAX is asynchronous so execution will proceed to the next line where result is undefined. The only way you can get data back from an asynchronous operation is to use a callback. A callback is a function that gets called when the asynchronous operation finishes what it is doing:
jQuery("#button").click(function () {
for (var i = 0; i < data.length; i++) {
updateUser(data[i], function(result) {
alert(result);
});
}
});
function updateUser(user_id, callback) {
jQuery.ajax({
url: "/users/update/" + user_id,
type: "GET",
success: callback
});
}
Here, you're calling the callback in the success handler of the AJAX call and so now you have access to the data that was returned by the AJAX call.
Have your function return the result of calling jQuery.ajax() - this object implements the jQuery deferred promise interface. That is, an object that promises to return a result some time later.
function updateUser(user_id) {
return jQuery.ajax({...});
}
and then use .done() to register the function to be called when the promise gets resolved:
updateUser(data[i]).done(function(result) {
alert(result);
});
The important part is that deferred objects allow you to complete decouple the initiation of the asynchronous task (i.e. your updateUser function) with what's supposed to happen when that task completes (or fails).
Hence there's no need to pass any callback functions to .ajax, and you can also chain your call with other deferred objects (e.g. animations, other AJAX requests).
Furthermore, you can register as many .done() callbacks as you like, and .fail() callbacks too, without ever having to change updateUser().
The A in ajax is Asynchronous, which means that when the file loaded, the function that started it is done running. Try using jQuery Deferred: http://api.jquery.com/category/deferred-object/
Example:
jQuery("#button").click(function()
{
for(var i = 0;i < data.length; i++)
{
updateUser(data[i]).done(function(result) {
alert(result); //prints 'undefined'
});
}
});
function updateUser(user_id)
{
return jQuery.ajax({
url:"/users/update/"+user_id,
type:"GET",
async: false,
success: (function(data){
...
})
});
}
The function that called the success function is the Ajax request and not the UpdateUser function. So obviously when you return it it will return back from the success callback but not to the UpdateUser function..
Also since the ajax is Asynchronous , buy the time the callback is executed it will come out of the UpdateUser function.. !
pretty sure what is happening (not an expert) but you are returning 'data' for your annonomys function in success and not your whole updateUser function
function updateUser(user_id)
{
var retData;
jQuery.ajax({
url:"/users/update/"+user_id,
type:"GET",
async: false,
success: (function(data){
//if I alert "data" here it shows up correctly
//but if i try to return it like below
//it does not get passed correctly
retData = data;
})
return retData;
});
But like i said, i am no expert.
I have a jQuery ajax call in a loop. However I do not want those ajax calls to be made simultaneously, I need the first ajax call to finish before going on to the next.
for (var i = 0; i < options.length; i++) {
jQuery.ajax({
url: "ajax_file.php",
data: //some data based on DOM tree
success: function(data){
//some DOM manipulation
}
});
}
I want the loop to continue executing only after the DOM manipulation in SUCCESS was executed (because the ajax call depends on the DOM tree).
In theory I know I could set the ajax call to be async:false, but it is not recommended as it can freeze the browser.
Because async: false is always a bad idea, I'd recommend something like this:
var recur_loop = function(i) {
var num = i || 0; // uses i if it's set, otherwise uses 0
if(num < options.length) {
jQuery.ajax({
url: "ajax_file.php",
data: //some data based on DOM tree
success: function(data){
recur_loop(num+1);
}
});
}
};
Setting async to false will do that. Keep in mind that the web browser might lock up while the requests happen if you do them asynchronously.
jQuery.ajax({
async : false,
url: "ajax_file.php",
data: //some data based on DOM tree
success: function(data){
//some DOM manipulation
}
});
you can do something like this (pseudo-code):
var i =0;
doLoop();
function doLoop() {
//exit condition
if (i >= options.length) {
return;
}
//loop body- call ajax
$.ajax({
//...
success: function(data) {
//do your thing
i++;
//go to next iteration of the loop
doLoop();
}
});
}