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)
Related
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 created a long polling using jQuery / PHP. and it is working perfectly. The issue is when a user click on other links or refresh the current page, it will hang on the current page till it get response from last AJAX request from server.
I have set about 30 sec in the server side to pick the latest data, means if someone sent a request to get the latest data, he cannot go to another page or refresh the current page till it returns the response. The worse case is, if the server didnt find the latest data, it will send the response after 30 sec.
I have use the following code to abort the request.
window.onbeforeunload = function(event) {
xhr.abort();
}
I have check on the console before and after execute xhr.abort() it shows readyState=1 and then readyState=0. Does this means xhr.abort() executed successfully? But why still the page hang on the current page till it returns the response.
Please help me to solve my issue. I don't want to wait until the server response when user click on other link or refresh page or do other stuff on the page.
This is my jQuery code
function setNoti(ntotal)
{
var t;
xhr = $.ajax({
type: "POST", url: myURL, data: "", dataType: "JSON", cache: false, async: true,
success: function(data) {
// do my work here
clearInterval(t);
t = setTimeout(function() {
setNoti(20);
}, 1000);
return false;
},
error: function()
{
clearInterval(t);
t = setTimeout(function() {
setNoti(0);
}, 40000);
return false;
}
});
}
You are assigning an xhr which can then be used to abort the request on subsequent calls to the function.
function setNoti(ntotal)
{
if (xhr) {
xhr.abort();
}
var t;
xhr = $.ajax({
type: "POST", url: myURL, data: "", dataType: "JSON", cache: false, async: true,
success: function(data) {
// do my work here
clearInterval(t);
t = setTimeout(function() {
setNoti(20);
}, 1000);
return false;
},
error: function()
{
clearInterval(t);
t = setTimeout(function() {
setNoti(0);
}, 40000);
return false;
}
});
}
No need for the window.onbeforeunload handler, which being a separate event is likely being called at the wrong time.
I have added session_write_close() in the server side and it is working perfectly. Following post helped me to find the solution :)
Multiple AJAX requests delay each other
I have a simple AJAX script that suppose to to call a PHP file and get data back.
window.addEvent('domready', function() {
$('dbform').addEvent('submit', function(e) {
new Event(e).stop();
var intervalId =setInterval(function()
{
var Ajax2 = new Request({
url: '/tools/getdata.php',
method: 'post',
data: 'read=true',
onComplete: function(response)
{
$('results').set('html', response);
}
}).send();
},1000);
var postString = 'subbutton=' + $('subbutton').value;
var Ajax = new Request({
url: '/tools/getdata.php',
method: 'post',
data: postString,
onRequest: function()
{
$('message').set('text', 'loading...');
},
onComplete: function(response)
{
$('message').set('text','completed');
clearInterval(intervalId);
},
onFailure: function()
{
$('message').set('text', 'ajax failed');
}
}).send();
});
});
The file that it is submitting too is.
$object= new compare();
if(isset($_POST['subbutton'])=='Run')
{
// This take about 5 minutes to complete
$run=$object->do_compare();
}
if(isset($_POST['read'])=='true')
{
/// in the mean time, the first ajax function is suppose to return data from here..while
// the do_compare() function finish.
// the problem is that it only return it once the do_compare() finish
///
echo 'read==true';
}
the script is working fine, expect, that when the Ajax request check the file every one second, it doesn't return any thing from $_POST['read'], till $run=$object->do_compare(); has finished.
why does it do that? what What I am trying to accomplish is that one Ajax function get data from do_compare function and the other ajax function also independently get that from the getdata.php file.
The problem is in line:
if(isset($_POST['subbutton'])=='Run')
isset returns boolean true or false so if $_POST['subbutton'] is set than it returns true and due to the weak type system of php true == 'Run' because 'Run' evaluates to true. Use
if(isset($_POST['subbutton']) && $_POST['subbutton'] === 'Run')
and
if(isset($_POST['read']) && $_POST['read'] === 'true')
Are you using session in the PHP AJAX handlers? If so, your session file is probably blocked.
Second: Javascript is internally single threaded in the browser (see google for more information).
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!
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.