I have requirement to manage 2 AJAX jQuery functions to start a process in the server and get the status from the server.
I,e. The first AJAX JQuery which will send a request to the server to start a particular process and returns back to the client with the status 'process-running'. The second AJAX JQuery function which will be called inside the success block of first function and its responsibility to query the status until it gets the response 'process-complete'.
Here is the psedo code I have
//This function which will be called on a button click
function buildApplication(){
//show the gif spinner in the front-end
$.when(buildApp()).then(function(result){
console.log('process-completed');
//hide the gif spinner in the front-end
});
}
function buildApp(){
return $.ajax({
type: 'POST',
url: 'url pointing to php script',
data: dataString,
cache: false,
success: function(result){
if(result == 'process-running'){
console.log('monitor starts');
getAppStatus();
console.log('monitor ends');
}
},
error: function(result){
}
});
}
function getAppStatus(){
console.log('Querying server');
return $.ajax({
type: 'POST',
url: 'url pointing to php script',
data: dataString,
cache: false,
success: function(result){
if(result == 'process-running'){
getAppStatus();
}
},
error: function(result){
}
});
}
The sleeping process is handled inside the PHP script of getAppStatus. I.e, If process is still running then the server will sleep for 10 seconds and then only returns response to the client.
The problem is both the functions are running asynchronous. That means the buildApp function invokes the getAppStatus function and just returns back immediately. The getAppStatus function runs as an orphan process.
How can I make it both synchronous (or similar) so that the parent caller will wait till the child to return back?
Note: I tried the async:false in the getAppStatus function but it freezes the browser and the ajax loader image stops spinning and it looks like hanged.
Related
I have a number input and "onChange" event, where I'm triggering this ajax request (see the code).
This aborting affects my next request.
If I'm sending only one request without aborting , the request has a normal speed but if I'm aborting, like 3 requests, the ajax looks like it's sending, in one request, all the aborted requests...
globalAjaxChange = $.ajax({
type: 'POST',
dataType: 'json',
url: ajaxUrl,
data: formData,
processData: false,
contentType: false,
beforeSend: function () {
if (globalAjaxChange != null) {
globalAjaxChange.abort();
}
},
success: function (data) {
if (data['ok'] == false) {
notify(data['msg'], 'error');
}
},
error: function (data) {
if (data.statusText !== 'abort')
notify('message', 'error');
}
});
Here is the network inspection:
Try returning try/false in your beforeSend callback. Unless you need to send the ajax request anyway, jQuery will abort the request for you with a return of false in that function. See the jQuery docs here for more info on the callback methods.
You also might be having a logic or async issue on the set of the globalAjaxChange variable. Which would cause the ajax request to always send by never returning null on your check for globalAjaxChange. Try placing breakpoints around where it sends and gets set at, to see what the values are.
Given the following code, can anyone help me understand why the first alert is executed after the second one? I believe this happens because ajax has a small delay untill it fetches the data, correct me if i am wrong.Thanks in advance.
Javascript code:
window.onload = function() {
arry = new Array();
jQuery.ajax({
type: "GET",
url: "index.php?op=17&id=##postID##&action=fetch",
dataType: "text",
success: function(response){
var e = response;
console.log(JSON.parse(e));
arry = JSON.parse(e)
alert(e); //1st alert
}
});
alert("test") //2nd alert
}
The first "A" in AJAX stands for asynchronous. That means that it is not blocking in your code, so the alert('test') is called immediately after your AJAX request, whereas alert(e) is only called once the AJAX request has received a successful response from the server.
The 'small delay' that you mention is not such, but rather the time it takes for the server to execute whatever code and return a response.
If you absolutely need the request to be handled synchronously, you can pass the async property to the AJAX call as follows:
window.onload = function() {
var arry = [ ];
jQuery.ajax({
type: "GET",
url: "index.php?op=17&id=##postID##&action=fetch",
dataType: "json",
async: false
}).done(function(response) {
arry = response
alert(response); //1st alert
});
alert("test") //2nd alert
}
Notice that I have updated the code somewhat to use the done() promise. Also, specifying dataType: "json" negates the need to call JSON.parse() on the response text.
yous first array is inside the success event of the AJAX call which (the success function) gets registered, skipped and called back only when the response of the ajax call is ready..
Can we programatically identify if a ajax call is executing in infinite loop.
Does it return any specific header when such thing happens? Can we identify this situation by headers in the response.
I have a set of ajax call and have taken care of most things, but still suspect that may be in some cases it might trigger infinite ajax call.
I make a set of ajax calls which are independent HTTP requests. I do certain calulcation of record processed by ajax call1 by sending another ajax call2.
$.ajax({
url:'<%= path1 %>',
method:"POST",
dataType: "script",
data: {
batch_id:<%= #id%>
}
});
$.ajax({
url:'<%= path2 %>',
method:"POST",
dataType: "script",
data: {
batch_id:<%= #id%>
}
});
Path 2 ajax calls are depended on path 1 ajax response. so if some varibales are not set properly when path1 ajax calls response or exception arise it may trigger unwanted behaviour or infinite ajax calls for path2 which will not understand when it has to stop since path1 ajax calls has ended abruptly.
instead of timeout is there a way from headers recived i can identify if a call is going around infinitely, so that i am sure that its not a long running request and that it needs to abort
Can anyone help?
The correct way would be to call second ajax only and only if the first one succeeded.
$.ajax({ url: path1,data: data }).done(function Ajax1Succeeeded() {
console.log("First done");
$.ajax({ url: path2, data: data }).done(function Ajax2Succeeeded() {
console.log("Both done");
})
}).fail(function Ajax1Error(){
console.log("First resulted in error");
});
EDIT: If your http requests are independent you could use promise
var ajax1 = $.ajax({url: path1});
var ajax2 = $.ajax({url: path2});
Promise.all([ajax1, ajax2]).then(function(response1, response2){
console.log("Both ajax call were successful");
}, function(){
console.log("There was an error");
});
You could use $.when()
$.when( $.ajax( "firstajax" ) ).then(function( data, textStatus, jqXHR ) {
// append data or what ever and then
//second ajax
});
the general rule is that the second ajax call should be done when the first one is finished. You can do it like this or simply add the second ajax call in the success method of your first one.
if your ajax call 2 totally depends on ajax call 1's success than you can execute your 2'nd ajax call only on success of 1'st ajax call success. use success method :
$.ajax({
url:'<%= path1 %>',
method:"POST",
dataType: "script",
data: {
batch_id:<%= #id%>
}
success : function (res){
secondAjax(); // call a function on success
}
});
function secondAjax(){
$.ajax({
url:'<%= path2 %>',
method:"POST",
dataType: "script",
data: {
batch_id:<%= #id%>
}
success : function(res){
alert('both ajax called successfully.');
}
});
}
I have a long running process that takes about 13-15 minutes to finish. The problem is that, the "complete" and "success" events are never executed. I can confirm from back end that the process has finished (can see updated time stamps in sql table), but on front end, the loading icon keeps spinning.
When I check the Network tab in IE Developer Tools, that specific request remains in "pending" state forever. Interestingly, if I run the same process in Firefox, it correctly execute the complete and success events.
Here is the code (pretty standard post request):
$.ajax({
type: "POST",
url: url,
data: JSON.stringify(params),
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
beforeSend: function () {
//Do something
},
complete: function () {
$('#overlay').hide();
},
success: function (retMessage) {
//reload page data
},
error: function () {
}
});
Please help, thanks.
I know this has been asked, probably, a million times, but for the life of me I cannot get anything to work.
I have a UI wizard control that on the "changed" event validates the model. If the model is not valid, it doe not allow the user to move forward in the wizard. I have tired using the $.when().done() feature in jquery, but my code still passes through before making sure the model is valid. The reason for calling an async ajax request is I do not want the UI to lock up so I can show some sort of progress indicator. I had set the async property to false, but my UI indicator would never show up. Here is an example of what my code is doing:
//the change event that is called when the user clicks 'next' on the wizard:
wizard.on('change', function (e, data) {
var isValid = $.validate({
"Model": [The_UI_MODEL],
"Url": [URL_To_Server_Validation],
"Async": true, //tells ajax request to send as async
});
//Tells the wizard not to move 'next' if the request comes back as not valid
if (data.direction === 'next' && !isValid) {
e.preventDefault();
}
}
//I am using the $.extend method for JQuery to create a function that will validate any model in my system.
validate: function(options) {
//Clear any previous validation errors
$.clearValidations();
var data = $.postJson(options);
//the result is getting returned before the $.postJson(options) finishes
return data.Success;
}
//I created my own method that extends the $.ajax method so I could do other things before /after a request:
postJson: function(options){
...other code for my application
//This is where I want the ajax request to happen and once done return the data coming back
//This is what I have tried, but it is not doing what I thought.
$.when(function(){
return $.ajax({
url: options.Url,
type: 'POST',
cache: false,
async: options.Async,
timeout: options.Timeout,
contentType: 'application/json; charset=utf-8',
dataType: "json",
data: JSON.stringify(options.Model),
error: function(xhr, status, error) {
...do stuff if ajax errors out
},
success: function (data) {
},
});
}).done(function(response){
//looks like i get back the responseText of the request. which is fine, but other posts i have read stated i should be getting back the request itself
...other UI stuff
return response;
})
}
KarelG is absolutely right. You need to refactor your code and do your valdiation check within the success callback of the ajax request.
Something like this...
wizard.on('change', function (e, data) {
$.ajax({
url: [URL_To_Server_Validation],
type: 'POST',
cache: false,
async: true,
contentType: 'application/json; charset=utf-8',
dataType: "json",
data: {"Model": [The_UI_MODEL]},
success: function (response) {
//Tells the wizard not to move 'next' if the request comes back as not valid
if(!response & data.direction === 'next')
{
e.preventDefault();
}
}
});
});
It looks like you're trying to write asynchronous code as if it were synchronous. An asynchronous call such as your $.validate() will return immediately without a result and continue on to the rest of your code. Anything you want to happen when the validate call finishes must be done in a callback function passed to it.
You can use jQuery promises (when, then, done, etc.) or another library such as async.js to help manage the control flow.
Also, this isn't particularly useful now since there's little to no browser support for it yet, but the yield operator plus a library such as Task.js will eventually let us write asynchronous code as if it were synchronous.