I have multiple check boxes for users to select and based on selected checkboxes i need to make a jquery ajax call. For that i used FOR loop to iterate through selected elements array and sent ajax request for each checkbox. Each request takes more than 5-10 minutes. In current scenario it calls all ajax request simultaneously.
I want to call next ajax calls only after finishing earlier ajax request.
Is there any solution for this?
You can make recursive calls.
function sendAjax(id) {
var checkbox = $('input[type=checkbox]:eq('+id+')','#formid');
if(checkbox == undefined)
return;
$.ajax({
type: 'POST',
dataType: "json",
url: 'url',
data: { },
success: function (data) {
sendAjax(id+1);
},
error: function (data) {
alert(data.responseText);
}
});
}
sendAjax(0);
Iterate in your readyStateChange method instead of in the for loop.
...
array_index++;
var data = selected_elements[array_index];
if (data) {
send_ajax_request(data);
}
}
That is kind of against the whole point of ajax. The first "a" is usually considered to mean "asynchronous", but you want to make the request synchronous (async = false I believe in jQuery)
Using recursive call, until previous ajax request not finished, next request cant be processed. So recursive call can solve the problem of these ajax request.
var queue_element = ["a","b","c","d","e","f","g"];
var execute_queue = function(i){
$.ajax( {
url: queue_element[i],
success: function({
i++; // going to next queue entry
// check if it exists
if (queue_element[i] != undefined){
execute_queue(i);
}
}
}); // end of $.ajax( {...
}; // end of execute_queue() {...
var index = 0;
execute_queue(index); // go!
Related
I am abit confused with idea of asynchronous and synchronous ajax calls.Is it possible to make one ajax call asynchrononously followed with a synchronous call??
Here's my scenerio,
I am trying to make a real time progress bar to show no of data inserted where postdata() inserts data into table while getprocess() function returns the current no of data inserted to show in a progress bar.
Reference:: making progress bar
function getprogress(data){
console.log(data);
$.ajax({
method: 'POST',
url: '<?php echo base_url()?>setting/processoffline/getprogressdata',
data:{ table:data },
dataType: 'json',
async: false,
success: function(val) {
var off=parseFloat(Number(val.dataoffline),10);
var on=parseFloat(Number(val.dataonline),10);
var percent=Math.round((off/on)*100);
// $('#'+data+'success').addClass('hidden');
console.log('offline- '+off);
console.log('online- '+on);
$('#'+data+'progressbar').css('width',percent+"%");
$('#'+data+'progressbar').html(percent+"%" + off+' out of '+on );
if(percent=='100'){
console.log(percent);
// $('#'+data+'progressbox').addClass('hidden');
$('#'+data+'success').removeClass('hidden');
$('.download').removeAttr('disabled','disabled');
// clearTimeout();
}
console.log(postComplete);
if (!postComplete)
setTimeout( function() { getprogress(data); }, 1500);
} ,
error: function() {
if (!postComplete){
setTimeout( function() { getprogress(data); }, 1500);
}
}
});
}
function postdata(data)
{
// if(!data)
$.ajax({
method: 'POST',
url: '<?php echo base_url()?>setting/processoffline/processdata',
data:{ master_table:data },
dataType: 'html',
success: function() {
postComplete = true;
},
error: function() {
postComplete = true;
}
});
}
Now here's how I call these functions for use
$(this).parent('td').parent('tr').siblings('tr').children('td').find('input:checked').each(function(){
data=$(this).attr('id');
postdata(data);
$('#'+data+'success').addClass('hidden');
$('#'+data+'progressbox').removeClass('hidden');
i++;
getprogress(data);
if(!postComplete)
setTimeout( function() { getprogress(data);}, 2);
Here postdata() function is called multiple times in loop asynchronously my case is that since loop can be for unlimited number, that can start lot of parallel processes that can hang up my system so .I need to start next loop for postdata() only when the earlier process is over.Function postdata() makes ajax call for php function that requires a lot of time.So my technique is to define postdata() function asynchronously so that I can call getprogress() function parallely but (don't know if possible) I want to call getprocess ajax call synchronously so that loop will wait until value returned from getprogress is over.In this way I can start a new process in ajax call only when earlier process is over.
I want to know if it is possible or not and if not how can i manage this issue.Sorry for bad english and If unclear please comment and I am stuck to this for 3-4 days.
Thanks in advance
To load the data when page scrolls down using function like this
$(window).scroll(function(){
if ($(window).scrollTop() == $(document).height() - $(window).height())
{
//alert('Scrolling Down');
get_summary_details(); //Here it calls AJax Function load the data
}
});
get_summary_details() function works fine when page scrolls down.This function is like this
function get_summary_details()
{
var dataString=[];
$('div.company_summary_data').each(function() {
var id = $(this).attr('id');
dataString.push(id);
});
$.ajax({
url:"getajaxcompanysummarydetails",
type:"POST",
//dataType: "json",
data:"last_app_data_id="+JSON.stringify(dataString),
success:function(data)
{
$('.company_summary_data:last').after(data);
}
});
}
My problem is
while get_summary_details() processing the Request user will go to top of the page and Scroll down , again this get_summary_details() function will execute.
How to prevent that Second Request Processing without completion of first Request.Is this Possible? Because of this i am getting duplicate records of data.I need to prevent to display duplicate records.
Thanks!
Your AJAX requests are most likely queueing up behind one another, because they are asynchronous, even though JavaScript itself is mostly single threaded.
You can use the abort() method to make sure only one request runs at a time. You need to assign the jqXHR object returned by $.ajax() to a variable:
please refer this link
You need to check whether the ajax request is busy by setting a boolean flag
var loadingSummaryDetails = false;
Set it to true when you start the Ajax and to false when the call finishes
function get_summary_details()
{
if(loadingSummaryDetails) {
return;
}
loadingSummaryDetails = true;
var dataString=[];
$('div.company_summary_data').each(function() {
var id = $(this).attr('id');
dataString.push(id);
});
$.ajax({
url:"getajaxcompanysummarydetails",
type:"POST",
//dataType: "json",
data:"last_app_data_id="+JSON.stringify(dataString),
success:function(data)
{
$('.company_summary_data:last').after(data);
}
}).always(function()
{
loadingSummaryDetails = false;
});
}
I have two ajax calls, one using .post() and the other using .ajax() (for testing). One is triggered as an interval check and the other send mail under a foreach loop. The problem is that the interval check only returns the results once the second ajax call has finished, not during - which is want I want to achieve. I get the results I want - just at the end of t My current code is:
$("#cdj-email-members").click(function() {
$(".cdj-email-content").slideUp();
$(".cdj-send-email").show();
// Disable the buttons
$("#save-email").hide();
$("#cdj-email-members").hide();
$("#cdj-test").attr('disabled','disabled');
// Declare the variables
var cdj_subject = $("#cdj-email-form #subject").val();
var cdj_content = $("#cdj-email-form textarea").val();
var cdj_fan_count = $("#cdj-progressbar").prop('max');
var cdj_email_members_nonce = $("#cdj_email_members_nonce").val();
// Set the interval check
setInterval(function(){
var data = {
'action': 'cdj_update_progress_bar',
};
$.post(cdjAjax.ajaxurl, data, function(response) {
var result = jQuery.parseJSON(response);
console.log(result);
$("#cdj-progressbar").attr('value', result);
});
},500);
// Send the Ajax request
$.ajax({
url: cdjAjax.ajaxurl,
type: 'POST',
data: {
action: 'cdj_email_members',
nonce: cdj_email_members_nonce,
'fan_count': cdj_fan_count,
'subject': cdj_subject,
'content': cdj_content
},
cache: false,
success: function(data) {
// Retreive the WordPress response
var status = $(data).find('response_data').text();
var message = $(data).find('supplemental message').text();
if(status == 'success') {
console.log(message);
$(".send-email-success").slideDown();
$(".send-email-success p.message").text(message);
$(".send-email-success").delay(4000).fadeOut();
// Enable the buttons
$("#save-email").show();
$("#cdj-email-members").show();
$("#cdj-test").prop('disabled', false);
// Switch back to content view
$(".cdj-email-content").delay(2000).slideDown();
$(".cdj-send-email").delay(2000).hide();
}
else {
console.log(message);
$(".send-email-error").slideDown();
$(".send-email-error p.message").text(message);
$(".send-email-error").delay(4000).fadeOut();
}
}
});
});
Thanks
The thing is that setInterval(function() {..},500); calls the function every 500ms, but the first call will only be áfter the first 500ms has passed, not immediately.
That's why $.ajax runs first.
What also happens is that both calls are over HTTP, and depending on your server configuration (simply said) two calls to the same URL can be lined up in a queue, so that's why $.ajax waits for $.post to finish.
To fix I would put the setInterval inside the $.ajax success function (making sure $.ajax gets called first, then running $.post in a 500ms interval afterwards)
I am using an Ajax request to post a form with Jquery.
$.ajax(
{
type: "POST",
url: "login.php",
data: $("#signin").serialize(),
dataType: "json",
cache: false,
success: function(data, textStatus) {
if (data.redirect) {
window.location.replace(data.redirect);
}
else {
$('#some').fadeOut(200);
$('#some2').fadeIn(200);
$("#some3").html(data.form);
$("#some").delay(2000).fadeOut(200);
$('#some2').delay(2800).fadeIn(300);
}
}
});
Now the ajax request will take place as soon as you click on a button "Login". The problem now is that if you press the button more than once the else case will be executed several times which will cause #some, #some2 and #some3 to fade out and in several times. So how could I check whether the request has allready been sent (without having to write something into my db)?
From here:
You can use .one() method and set it again in ajax callback.
function doAjax(){
// Your Ajax call.
$.ajax({..., complete: function() {
// Ajax call done, re-enabling the button/link
$("#buttonId").one('click', doAjax);
}, ...});
}
$("#buttonId").one('click', doAjax);
Make boolean flag, say, login_in_process, on login check this flag in true value. And check this flag on every click if it true then make empty return. In success and error callbacks set it in false state.
You can use a boolean value to record whether or not it has been clicked:
var loginClicked = false;
$('input_button_element').click(function(){
if (!loginClicked) {
loginClicked = true;
// your js here - you may want to add some visual feedback to the user also
}
});
You will have to store a boolean in a global scope, e.g. one stored on the window object:
if (!window.isClicked) {
window.isClicked = true;
...Do your ajax call here
}
Remember to ALWAYS restore the value of window.isClicked, not only in the success callback of ajax():
var jqxhr = $.ajax( ... )
.done(function() { })
.fail(function() { })
.always(function() { window.isClicked = false });
you can make a global var
var loginClick = false;
Inside your method you first check that value
if (!loginClick) {
loginClick = true;
//your ajax code;
}
I'm trying to get some data from a PHP script in a project right now. All examples I found searching for AJAX callback functions "use" the data already in the callback itself, but I want to fetch data and store it in a way ready to be returned.
function getEle (id) {
var element = [];
$.ajax({
url: 'slides.php',
type: 'POST',
data: {"id": id},
success: function(data) {
var content = data;
element[0] = id;
element[1] = content;
// if I alert(element[1]); here it will work!
}
});
alert(element[1]); // here it just won't :/ ("undefined")
return element;
}
Somewhere in my script some function needs to getEle(ments) but all I get is undefined.
is there a way to do what I want? Or is there maybe a better way to do this?
A solution would be to pass a callback function to getEle():
getEle(id, callback){
$.ajax({
/* some options, */
success: function(){
var content = data;
element[0] = id;
element[1] = content;
callback(element);
}
})
}
And then pass a function containing the code of what to do when you have the element content:
getEle('myId', function(element){
alert(element[1]);
});
Two things are failing here:
Variable scope - You define the variable content inside the AJAX callback. This makes it inaccessible from the surrounding code. You could omit the var and just write content = data which makes it accessible globally.
Asynchronicity - Becaus AJAX is asynchronous the script following the callback will be executed before the callback was executed. The only way to solve that problem is to use the callback as it's intended to.
Take a look at this.
function getEle (id, callback) {
var element = [];
$.ajax({
url: 'slides.php',
type: 'POST',
data: {"id": id},
success: function(data) {
var content = data;
element[0] = id;
element[1] = content;
callback(element);
}
});
}
}
getEle ("someID", function(someElement) {
alert(someElement);
});
Here's what's happening in your code:
the array "element" is initialized.
the AJAX call is made with a success callback function
while it's waiting for that AJAX to run, it goes ahead with the rest of your code and alerts element[1], which doesn't exist yet
the success callback runs and populates the array "element".
You might consider a global variable to solve this:
var element = [];
function getEle (id) {
$.ajax({
url: 'slides.php',
type: 'POST',
data: {"id": id},
success: function(data) {
var content = data;
element[0] = id; // the global "element" is set
element[1] = content;
}
});
}
// element[0] will exist now, but only after the AJAX call is complete
Alternatively, you could turn your AJAX into a synchronous call:
function getEle (id) {
var element = [];
$.ajax({
async: false, // forces synchronous call
url: 'slides.php',
type: 'POST',
data: {"id": id},
success: function(data) {
var content = data;
element[0] = id;
element[1] = content;
}
});
alert(element[1]); // now it is set
return element;
}
The only other option I can see is to keep everything tied up inside the "success" callback, which you already discovered works fine.
Your callback executes some time after the rest of your code finishes.
You need to pass the value back using a callback, the way $.ajax does.
Your alert ends up being undefined because the AJAX call is asynchronous. So while that AJAX call is waiting for the server's response, the script continues on to the alert, at which point element[1] is not yet defined.
You should place your return element line inside of the success callback function.