I am having some trouble with the timing of javascript events. The problem I am having is that one part of the code seems to be executing before another part of the code completes. I need to ensure that the first code finishes before the latter code begins. Here is the initial code:
function(){
myLoop(); //this needs to complete before the call to myMethod below
$.ajax({
url: sURL + "myController/myMethod",
success: function() {
$.msg("My Success Message",{live:10000});
error: function(){
$.msg("My Error Message",{live:10000});
});
}
And here is the code that loops and inserts records into a db:
function myLoop(){
$('input[name=c_maybe].c_box').each(function(){
if( $(this).prop('checked') ){
var rn = $(this).prop('value');
$.ajax({
url: sURL + 'myController/myInsert',
type:"POST",
dataType: 'text',
data: {'rn': rn},
success: function(data) {
//not sure what to do on success.
}
});
}
});
}
The problem that seems to be happening is that the call to myController\myMethod is happening before myLoop completes inserting all the records into the database.
Can someone suggest a way for me to redesign this code so that I can ensure that myController\myMethod is not called until myLoop has completely finished?
Thanks.
function myLoop() {
var jqxhrs = [];
if( $(this).prop('checked') ){
var rn = $(this).prop('value');
jqxhrs.push($.ajax({...
}
return jqxhrs;
}
function () {
$.when.apply(undefined, myLoop()).done(function () {
$.ajax({
url: sURL + "myController/myMethod",
...
});
}
$.when.apply is used to call $.when on the array of ajax requests, so .done is not called until they are all complete.
You can use the $.when function that has been added to jQuery.
It goes something like this:
$.when(ajaxFunction1(), ajaxFunction1()).done(function(response1, response2){
// when the function calls are done this code here will be executed -> the response will be passed as parameters corresponding to the functions -> response1, response2
});
Or you can try to use "beforeSend" within the ajax function:
$.ajax({
beforeSend: function(){
alert("doing stuff before the ajax call ...");
},
success: function(){
alert("Whoa!");
}
});
You can make the ajax call synchronous. That way, the execution will be blocked till ajax call returns:
$.ajax({
url: sURL + 'myController/myInsert',
type:"POST",
dataType: 'text',
data: {'rn': rn},
async: false,
success: function(data) {
//not sure what to do on success.
}
});
Related
I am trying to get the response time of an ajax request and use it in a setTimeout() function, this function displays a loader that is suppose to keep loading until we get the response.
Here's my function :
$("#recalculer").click(function(){
ajax_call();
setTimeout(function()
{
$("#divgris").fadeTo(0,1);
$("#loadingdiv2").hide();
}, 5000);
});
And here's my ajax request :
function ajax_call()
{
var resultat;
var duree_souhaitee= $("#duree").val();
var apport_personnel= $("#apport").val().replace(/\s+/g, '');
var prix_achat_bien=$("#prix").val().replace(/\s+/g, '');
$.ajax({
type: "POST",
url: "/iframe/rest-assurance",
data : {
"duree_souhaitee" : duree_souhaitee,
"apport_personnel" : apport_personnel,
"prix_achat_bien" : prix_achat_bien
},
dataType: 'json',
xhrFields: {
withCredentials: true
},
async: true,
beforeSend: function(){
$("#actualiserAssurance").hide();
},
success: callback_assurance
});
}
For now i set a time of 5000 but i need to replace it with the ajax response time, how can I achieve that ?
I use always:
$("#loadingdiv2").show();
$.ajax(
...
).always(function(){ $("#loadingdiv2").hide(); });
If you want to separate it from the Ajax call I would use a custom event.
$("#recalculer").click(function(){
ajax_call();
});
$("body").bind('custom.ajaxStart', function(){ $("#loadingdiv2").show(); });
$("body").bind('custom.ajaxStop', function(){ $("#loadingdiv2").hide(); });
function ajax_call(){
$('body').trigger('custom.ajaxStart');
$.ajax(..).always(function(){ $('body').trigger('custom.ajaxStop'); });
}
The always callback is triggered even on a 404, relying on timing never works well for me.
Using an event gives you the flexibility of calling the loading deal, from anywhere.
Meaby the you can use:
console.time(label);
and
console.timeEnd(label);
more info can be found here.
Goodluck!
use
var afterfnc = ()=>{
$("#divgris").fadeTo(0,1);
$("#loadingdiv2").hide();
}
and then set
callback_assurance = afterfnc
in ajax call
I have a code like this:
object1 = $.ajax({
..
..
});
In the event of error I want to be able to restart the ajax, for example, if the connection of the user drops I want to be able to call the same ajax again without having to make $.ajax(.....). Is it possible to do something like:
object1.restart();
?
put it in a function:
function callAjax() {
$.ajax({
..
..
});
Then its like callAjax() if theres an error..
That is easy, and jQuery allows you to do that inside an Ajax request. Have a look
$.ajax({
/* full ajax body */
url: 'page.html',
data: 'if-any',
success: function () {
/* show that ajax request has finished */
},
error: function () {
/* restart the ajax request, by re executing the function */
}
});
You can try this:
function ajax_request () {
$.ajax({
/* full ajax body */
url: 'page.html',
data: 'if-any',
success: function () {
/* show that ajax request has finished */
},
error: function () {
ajax_request(); // using this, you can re execute the function
}
});
}
$.when() is a potential candidate here,
for eg.
var object1 = $.ajax({
..
..
});
$.when(object1).fail(object1);
I'm writing a javascript function that should change the view of a postcard depending on which case is selected.
My problem is that the old values of the object "m_case" is getting used. If I press the button with class "case-btn" twice I get the right case selected in my postcard view. But I want it to be triggered when I press the button once.
I guess I have to do something like a callback function in the m_case.setCase() function call, but I can't get it working,
$('.case-btn').on('click', function() {
remove_active_state_from_cases();
m_case.setCase($(this).data('case'));
// Changes the view of the postcard
m_postcard.changeBackground(m_case.getPhoto());
m_postcard.changeMessage(m_case.getMessageText());
m_postcard.changeFullName(m_case.getFullName());
m_postcard.changeCountry(m_case.getCountry());
$(this).toggleClass('active');
});
The setCase() function
this.setCase = function(id) {
// Set ID
this.setID(id);
var that = this;
$.ajax({
url: 'get_case_by_id.php',
type: 'get',
dataType: 'json',
data: {id: that.getID() },
success: function(data) {
if(data.success) {
that.setFirstName(data.first_name);
that.setFullName(data.full_name);
that.setAdress(data.adress);
that.setCountry(data.country);
that.setStamp(data.stamp);
that.setPhoto(data.photo);
that.setSummary(data.summary);
that.setStory(data.story);
that.setMessageText(data.message_text);
that.setDefaultMessageText(data.default_message_text);
that.setMessageImg(data.message_img);
} else {
console.log('failure');
}
}
EDIT The problem might be in my AJAX call, I have to wait till the ajax have been called. but how do I continue the first flow when my Ajax is done and not before?
SOLUTION
I made it working by adding a callback parameter and calling that function in the ajaxs complete function.
$('.case-btn').on('click', function() {
remove_active_state_from_cases();
var that = this;
m_case.setCase($(this).data('case'), function() {
m_postcard.changeBackground(m_case.getPhoto());
m_postcard.changeMessage(m_case.getMessageText());
m_postcard.changeFullName(m_case.getFullName());
m_postcard.changeCountry(m_case.getCountry());
$(that).toggleClass('active');
});
});
// Sets the whole case from an id.
this.setCase = function(id, callback) {
// Set ID
this.setID(id);
var that = this;
$.ajax({
url: 'get_case_by_id.php',
type: 'get',
dataType: 'json',
data: {id: that.getID() },
success: function(data) {
if(data.success) {
that.setFirstName(data.first_name);
that.setFullName(data.full_name);
that.setAdress(data.adress);
that.setCountry(data.country);
that.setStamp(data.stamp);
that.setPhoto(data.photo);
that.setSummary(data.summary);
that.setStory(data.story);
that.setMessageText(data.message_text);
that.setDefaultMessageText(data.default_message_text);
that.setMessageImg(data.message_img);
} else {
console.log('fail big time');
}
},
complete: function() {
callback();
}
});
}
Your m_postcard.changeBackground and other calls should be in the success callback, or in another function that is called from the success callback, as those values aren't set till the async ajax call is done.
With the way your code is now the m_postcard.changeBackground and other calls are called immediately after your setCase function is done executing. This means your methods are executed before the data has arrived from the server
While the ajax is processing you probably should show a loading message on the screen to let the user know they have to wait till the processing is done. Show the message before calling the .ajax call and hide it in the success/error callbacks.
Any changes to the site content should be done from the success callback, ie changing active states, changing content, etc.
I am using jQuery getJSON() function. This function getting data with no problem. But sometimes waiting, waiting waiting... And my loading bar showing loading loading loadin at center of page.
So jQuery ajax() function have an timeout variable. But i want to use getJSON function. And i think that i can use ajaxStart() and ajaxStop() functions. But how?
$('.loadingDiv')
.hide()
.ajaxStart(function() {
$(this).fadeIn();
setTimeout("throw '';",15000) //i used this but didn't work
setTimeout("return;",15000) //i used this but didn't work
setTimeout("abort();",15000) //i used this but didn't work.(Abort all ajax events)
})
.ajaxStop(function() {
$(this).fadeOut();
});
getJSON() returns a promise on which you can call the abort function :
var p = $.getJSON(..., function(){ alert('success');});
setTimeout(function(){ p.abort(); }, 2000);
EDIT : but if your goal is just to abort if it takes too much time, then lethal-guitar's answer is better.
getJSON() is just a shorthand for the following:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
So you could use $.ajax() and specify the timeout option as desired. See also: http://api.jquery.com/jQuery.getJSON/
As lethal-guitar mentioned getJSON() function is just an shorthand for $.ajax(). If you want to detect if a timeout has occurred rather than an actual error use the code below.
var request = $.ajax({
dataType: "json",
url: url,
data: data,
success: function( ) { },
timeout: 2000
}).fail( function( xhr, status ) {
if( status == "timeout" ) {
// do stuff in case of timeout
}
});
There's always the nuclear route as well:
//Set AJAX timeout to 10 seconds
$.ajaxSetup({
timeout: 10*1000
});
This will set all the AJAX requests your program makes (even via $.getJSON) to have a time out of 10 seconds (or what have you).
the setTimeout function executes a set of code after a specified number of milisecons in the global scope.
The getJSON function (per the jQuery documentation here http://api.jquery.com/jQuery.getJSON/) is shorthand for:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
so you would want to make your call like so:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success,
timeout: 15000
});
$('.loadingDiv')
.hide()
.ajaxStart(function() {
$(this).fadeIn();
})
.ajaxStop(function() {
$(this).fadeOut();
});
I don't think any of these answers are ideal. I know this is years late, but what you want to do is use the success/error callback options of the .ajax(); method when receiving a JSONP response.
Example of how I would structure this:
// Call
$.ajax({
// URL you want to get
url: 'http://example.com/json?callback=?',
// Set a realistic time in milliseconds
timeout: 3000,
// Put in success callback function here, this example
// shows you the data you got back from the call
success: function(data) {
console.log(data);
},
// Put in an error handling function, just an alert in this case
error: function(badData) {
alert('The call was unsuccessful');
},
type: 'POST'
});
My scripts are working perfectly fine. However, the content does not refresh itself to get new data. Why is it so?
function updateMsg() {
$.ajax({
url: "/recent/notifications/",
cache: false,
success: function(html){
$("#profile_notifarea_msgbox").html(html);
}
});
setTimeout('updateMsg()', 4000);
}
updateMsg();
Your setTimeout can reference updateMsg directly instead of using a string:
var timeout;
function updateMsg() {
$.ajax({
url: "/recent/notifications/",
cache: false,
success: function(html){
$("#profile_notifarea_msgbox").html(html);
timeout = setTimeout(updateMsg, 4000);
}
});
}
updateMsg();
function stopUpdate() {
clearTimeout(timeout);
}
To stop the continuous update you save a reference to the setTimeout in a variable and then call clearTimeout and pass in that variable. In this example, you would just call the function stopUpdate() to cancel the updates.
when you use ajax with jQuery try to always put an error function, in this way you can identify if something is wrong with the request