Need assistance in ajax spinner displaying - javascript

I am making an ajax request which actually looks like this.
$loading = $("#loadingDiv")
function loadBuildList() {
$.ajax({
async:true,
url:"ajax_test.php",
beforeSend : function() { $loading.show(); },
success : function() { $loading.hide() }
});
}
Now, I need to display a spinner image while the ajax is running, Also my code is not supposed to execute further until the ajax's execution is over. If I make async:false I will not be able to load the spinner. If I make async:true I will not be able to wait till ajax execution is over.
Below is how I am calling the function loadBuildList
...
//$loading.show(); // this I will use when aync : false
loadBuildList()
//$loading.hide();
...
How can I handle such situation? Can anybody please help me with this?

You should never use async:false, or you'll stop the whole execution thread until it has got a response.
Everything that needs to be run after an async execution, in this case $.ajax needs to be written inside the callback. That is inside success for JQuery $.ajax.
$loading = $("#loadingDiv")
function loadBuildList() {
$.ajax({
async:true,
url:"ajax_test.php",
beforeSend : function() { $loading.show(); },
success : function() {
$loading.hide();
// Stuff after $.ajax goes here.
},
fail: function() {
// Or here.
}
});
}
You should also have a read at How do I return the response from an asynchronous call?

On the basis of code snippet you have provided it seems there is no need to use beforeSend as you just have one call on the page. You can do it following way.
$loading = $("#loadingDiv");
function loadBuildList() {
$loading.show(); // Show spinner before AJAX call
$.ajax({
async:true,
url:"ajax_test.php",
// beforeSend : function() { },
success : function() { $loading.hide() }
});
}
You can still try to make it as mentioned by #zurfyx but usually this practice is followed when you need something centralized and not for individual AJAX calls.

Handling the spinner is fine with .complete (so picks up both success and error):
function loadBuildList() {
var loading = $("#loadingDiv")
loading.show();
$.ajax({
url:"ajax_test.php",
complete : function() { loading.hide() }
});
}
However, this comment is more interesting:
my code is not supposed to execute further
It's not that you don't want to execute further, it's that you want to continue execution when the ajax call has completed.
You can do this by returning the $.ajax object, which is a promise. With the promise, you can then add chain calls in your own code. This is similar to using a callback parameter, but generally more flexible:
function loadBuildList() {
return $.ajax({
...
}
// calling code
loadBuildList().done(function() {
// code to run when the list has loaded
});

Related

jquery plugin - make ajax call chainable

I am trying to write a jquery plugin.
Now, I would like to use an ajax-call in one of the functions of this plugin.
However it should be chainable, meaning in this case that the ajax-call should be executed and only after something was returned, the return should happen.
I tried different things but so far I could not make it so that the second function in the chain is really executed after the return value of the ajax call was retrieved;
In this version (see below) I can use
$(document).createDatabase().message();
So, chaining works.
But looking at the console log – the message() function is executed before the ajax-call in createDatabase() is finished.
How can I make it so that
$(document).createDatabase().message();
first returns the output/return of the ajax-call that is inside createDatabase() and only after that message() is executed?
Code:
(function($) {
$.fn.createDatabase = function(options) {
// Plugin options defaults
var settings = $.extend({
name: 'NA',
onExit: function() {} // callback function
}, options);
$.ajax({
method: "POST",
url: "plugin/php/createDatabase.php",
data: settings
})
.done(function(msg) {
console.log("createDatabase executed with message: " + msg);
settings.onExit.call();
});
return this;
};
$.fn.message = function() {
console.log('this should appear after the console-log message of createDatabase');
return this;
}
}(jQuery));
Thank You!
You could do a couple of things, but they are all a bad idea. The reason is that these are two separate jQuery plugins - a plugin should be capable of working on its own. There is no guarantee or reason that somebody won't do .message().createDatabase(). If you need to guarantee the order of execution, then you should use just one plugin. One possible way would be to pass message inside options when you call .createDatabase(options), and then run message when the call is done. Like so
$(document).createDatabase({
message: function() {...}
});
...
var promise = $.ajax({
method: "POST",
url: "plugin/php/createDatabase.php",
data: settings
})
.done(function(msg) {
console.log("createDatabase executed with message: " + msg);
settings.onExit.call();
});
...
if ( settings.message )
promise.done( settings.message.bind(this) );
I tried different things but so far I could not make it so that the second function in the chain is really executed after the return value of the ajax call was retrieved;
The second function executes when the first one finishes. The first one finishes with return this, but this happens before the ajax call is done because ajax calls are asynchronous.

Rails best way to initialize function in Javascript after ajax and document ready

The question is that there are some functions that I call to initial some elements on the page. But after ajax success, I have to re-call those functions again and again in multiple places. I was wondering beside using the following combo
$(document).ready(function(){
function A
});
$(document).ajaxComplete(function(){
function A
});
I read that there are something I can do with the setTimeout and clock up the thread to delay the function call from the link http://googlecode.blogspot.com/2009/07/gmail-for-mobile-html5-series-using.html
but I have a hard time digesting it. If someone can break it down for me.
Update:
I meant that when I do an html updated inside multiple ajax success, I have to call function A to re initialize and the code above is my idea but I think there should be a better way
Example
$(document).on('click', 'a', function() {
$.ajax({
type: 'GET',
url: 'some url',
data: data,
success: function(data) {
$('#some-sector').html(data);
function A; <------- to init
}
});
});
$(document).on('click', 'b', function() {
$.ajax({
type: 'GET',
url: 'another url',
data: data,
success: function(data) {
$('#some-sector').html(data);
function A; <------- to init
}
});
});
Another Update:
So Basically there are some elements on the page that I need to update dynamically by calling function A. And from the example, I have multiple ajax that updates a page. Instead of calling function A in multiple the ajax success, I was wondering if there is a better way to do this. The only thing that i could think of it's the top code.
As far as i understand you are calling some group of functions on DOM ready
function as
$(document).ready(function(){
function_01();
function_02();
function_03();
});
and want to call the same function on the ajax request
$(document).ajaxComplete(function(){
function_01();
function_02();
function_03();
});
You can define a common function that call internally all the functions that are in need
function callAll()
{
function_01();
function_02();
function_03();
}
and then call as the following
$(document).ready(callAll);
$(document).ajaxComplete(callAll);
at what logic you want to cal this callAll method again and again..
update
try calling the function as below
$(document).ready(function () {
function callall()
{
alert("call all");
}
$(document).ajaxComplete(callall);
});
and this will call the initialize function after the ajax request is processed
Hope it helps...........

execute js function when a function inside document.ready is done

I have a website which computes the performance of each server. One of the requirements is the center partial page which are about performances must be finish loading first before doing another function in the background.
This center partial page uses ajax calls. They are being defined at the document.ready of the js file:
$(document).ready(function () {
// ajax call here
// another ajax call here
// third ajax call here
});
Then the function that I wanted to execute after the function inside the document ready is done:
function functionA() {
// some codes here
});
I tried using this:
$.when(document).ready(function () {
}).done(functionA);
but I can't make it run .. Any suggestions would be gladly appreciated. Thanks in advance!
The first letter in AJAX stands for asynchronous which means that at the end of your document.ready event, they could be off somewhere else doing some processing. The document.ready will not wait for them to finish.
You need to set up jQuery using .when to tell you when all three AJAX calls are complete:
// Document.ready
$(function() {
// Any synchronous code you may do on DOM ready goes here
// Set up the promise
$.when(
// Pass in all your AJAX calls.
$.ajax({ url: "/AjaxCall1?param=true" }),
$.ajax({ url: "/AjaxCall2?param=1" }),
$.ajax({ url: "/AjaxCall3?param=yup" })
).then(function() {
console.log("All AJAX requests finished");
}, function() {
console.log("Something went wrong :(");
});
});
Here is a way to deal with DOM ready event and Ajax calls at the same time :
var init, ajax1, ajax2, domready;
ajax1 = $.ajax({ url: '/1' });
ajax2 = $.ajax({ url: '/2' });
domready = $.Deferred();
$(domready.resolve);
init = $.when(domready, ajax1, ajax2);
http://api.jquery.com/category/deferred-object/
Then you don't need to care about the code above any longer :
init.done(function () { alert('success'); });
init.fail(function () { alert('failure'); });
init.done(function ($, response1, response2) {
alert(response2[0]); // shows the data from the second Ajax call
});
Here is a live demo : http://jsfiddle.net/wared/s22dT/.
About your try, jQuery.when() returns a Promise object which has no ready method :
$.when().ready() // TypeError: Object #<Object> has no method 'ready'
http://api.jquery.com/jQuery.when/

Unexpected javascript function behaviour

What I want is to add a loader bar to my HTML, while my method does some time consuming AJAX calls and DOM manipulation.
The problem is, that show() method won't show the loader bar until the AJAX calls are done, how do I fix this?
I want to force the show() method, then do AJAX calls and DOM stuff, then force the hide() method.
Method doing AJAX calls:
$('.my-button').on('click', function(){
$('#display-loader').show();
// ajax and dom manipulation
$('#display-loader').hide();
});
EDIT: Seems like there's some misunderstanding as to what my problem is. If I change my code to this:
$('.my-button').on('click', function(){
$('#display-loader').show();
// ajax and dom manipulation
});
It still won't SHOW the loader bar, untill the AJAX methods are done, it's like it skips the show() method, does AJAX stuff, and then calls the show() afterwards.
All the AJAX calls have async set to false. I have 5 AJAX calls, and each AJAX call relies on the data fetched from the previous call, I have no way to set the async to true, is there a way to get around this, and force the DOM to display the image, and then do AJAX calls?
you can do next:
showLoader();
$.ajax({
type : 'POST',
url : url,
data : postData,
success : function (returnData) {
},
error : function (xhr, textStatus, errorThrown) {
},
complete : function (){
hideLoader();
}
});
You need to call hideLoader() within AJAX success function, to hide after ajax operation. As AJAX is asynchronous, so in your code hideLoader() execute before finish ajax call and done dom stuff.
$('.my-button').on('click', function(){
showLoader();
$.ajax({
....
success: function() {
hideLoader();
}
});
});
according to #Esailija comment to hide after complete callback do like:
$('.my-button').on('click', function(){
showLoader();
$.ajax({
....,
success: function(){
},
complete: function() {
hideLoader();
}
})
});
I recommend maybe the following way:
$.ajax({
.....
}).done(function () {
hideLoader();
});
This will insure the loader goes away. If your ajax isn't successful then the success callback will never be reached and then the loader will stay on the page.
But it depends on the scenario. You can also just put it in your error callback.

How to extract ajax response data from the success callback

Sorry if this is a duplicate but I couldn't find any satisfying answers in the previous posts.
$(function() {
$.ajax({
url: 'ajax/test.html',
success: function(data) {
// Data received here
}
});
});
[or]
someFunction() {
return $.ajax({
// Call and receive data
});
}
var myVariable;
someFunction().done(function(data) {
myVariable = data;
// Do stuff with myVariable
});
The above code works just fine. However, this ajax request is made on page load and I want to process this data later on. I know I can include the processing logic inside the callback but I don't want to do that. Assigning the response to a global variable is not working either because of the asynchronous nature of the call.
In both the above ways, the 'data' is confined either to the success callback or the done callback and I want to access it outside of these if possible. This was previously possible with jQuery 'async:false' flag but this is deprecated in jQuery 1.8.
Any suggestions are appreciated. Thank you.
You can "outsource" the callback to a normal function, so you can put it somewhere, you like it:
$(function() {
$.ajax({
url: 'ajax/test.html',
success: yourOwnCallback
});
});
somehwere else you can define your callback
function yourOwnCallback(data) {
// Data received and processed here
}
this is even possible with object methods as well
This solution might not be idea but I hope it helps.
Set the variable upon callback.
Wherever you need to process the data, check if variable is set and if not wait somehow.
Try:
$(document).ready(function(){
var myVar = false;
$.ajax({
url: 'ajax/test.html',
success: function(data) {
myVar=data;
}
});
someFunction(){ //this is invoked when you need processing
while(myVar==false){}
... do some other stuff ..
}
});
Or
someFunction(){
if(myVar==false){
setTimeout(someFunction(),100); //try again in 100ms
return;
}
.. do some other stuff ..
}

Categories