When the user refreshes the page, defaultView() is called, which loads some UI elements. $.address.change() should execute when defaultView() has finished, but this doesn't happen all the time. $.address.change() cannot be in the success: callback, as it's used by the application to track URL changes.
defaultView();
function defaultView() {
$('#tout').fadeOut('normal', function() {
$.ajax({
url: "functions.php",
type: "GET",
data: "defaultview=true",
async: false,
success: function (response) {
$('#tout').html(response).fadeIn('normal');
}
});
});
}
$.address.change(function(hash) {
hash = hash.value;
getPage(hash);
});
I'm at a loss as to how to make $.address.change() wait for defaultView() to finish. Any help would be appreciated.
Call it in the success or complete callback. Using delay for timing a callback is unreliable at best. You might even need to put the call to it in the callback to the fadeIn function inside of the success callback.
It doesn't have to be defined inside the success callback, just executed. Both contexts will still be able to use it.
I too was told that because of async you can't make javascript "wait" -- but behold an answer :D ...and since you're using jQuery, all the better:
use jQuery's bind and trigger. I posted an answer to a similar problem at How to get a variable returned across multiple functions - Javascript/jQuery
One option is to hide the $.address (I'm guessing this is a drop-down list) via css, and show it inside the success callback from the ajax method.
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
I'm having trouble with callbacks mainly because I don't understand how they're working (or supposed to work).
I have my function:
function checkDuplicateIndex(values, callback) {
$.ajax({
type: "POST",
url: url,
data: "command=checkIndexAlbumTracks&" + values,
dataType: "html",
success: function(data){
var returnValue = data.d;
callback(returnValue);
}
});
}
And then within a submit event, how do I properly call checkDuplicateIndex so that I can alert() the value?
This ended up being a long answer, so I'm going to try to split it into pieces.
Functions in Javascript
So within javascript, a function is an object that can be passed around, assigned to a variable, etc, just like any other data type. The difference is that a function, rather than being a string of text, number, etc, is a block of code waiting to be executed.
This is often confusing to people starting out with programming because usually when you write code, it is executed when you run the program. But for functions, this is not the case. When you write code inside a function, it waits there not executing until you call the function. If you do not call the function, the code is never executed. Let's check out a quick example:
function say_hello(){
console.log('hello!');
}
What you see here is called a function declaration. This means you are creating a function, which is a block of code waiting to be executed. If you run this code, nothing will be logged to the console. Now let's look at a function call.
function say_hello(){
console.log('hello!');
}
say_hello();
So here we declare the function just like before, but below we call it. A function call is just the name of the function followed by open and close parens. If the function takes arguments, they will be inside the parens, but no need to worry about that for now. If you were to run this code, you would in fact see hello! logged to the console, because the function was called, which executes the code inside.
Asynchronous Code
Now, let's switch gears for a second. When you make a jquery ajax call, jquery abstracts a lot of code into the library. They take care of setting up the XMLHttpRequest, firing it off to the place you specify, and collecting the result, and they do this in a way that works cross-browser. But since javascript is asynchronous, as soon as the ajax call goes off, javascript keeps executing code after the ajax call, because who wants to wait around for someone else's server to respond while you could be still getting in that work. So if you fire off something like this:
$.ajax({
url: 'http://google.com',
success: function(){ console.log('done!') }
});
console.log('after ajax call');
...you may be surprised to find that it logs after ajax call before logging done!. This is because, as stated earlier, in javascript calls that deal with I/O are often asynchronous.
So if the ajax call is made and it immediately continues executing code even if the ajax call has not finished, how can we specify code that will run when it's finished? This is where everything comes together. By providing jquery with a function, which as we remember is a block of unexecuted code, we can provide a way for ourselves to write code that is executed only after the ajax call has finished by passing the block of unexecuted code to jquery and saying essetially "hey jquery, take this code, and when the ajax call is finished, call it and pass in any data you got out of it." How convenient!
The way we do this is through the success and error properites of jquery's ajax function. If the request was successful, it will call the function we pass to success, and I assume you can guess what happens if there was an error.
Putting It All Together
Asynchronous code and first class functions are two of the most confusing parts about javascript, and once you understand these two concepts, you'll be in a great spot, although it may take a while to get there. So it's important to think carefully about it and experiment. Let's talk through a couple ways to handle the example you are working with here, about jquery ajax.
First, we can try making our own function and passing the name of the function to the success handler. Then when it comes back, it will call the function. Let's take a look:
var my_callback = function(data){
console.log(data);
}
$.ajax({
url: 'http://google.com',
success: my_callback
});
This is an interesting way of doing it. Here we have assigned an anonymous function to a variable, then passed the variable name to the success handler. This will work fine. Now let's try another way:
function my_callback(data){
console.log(data);
}
$.ajax({
url: 'http://google.com',
success: my_callback
});
Here, we define a named function and do the same thing. This will work the same way. Named functions in javascript can actually be declared after the are used, so you could move the function declaration below the ajax call and it would still work. Try this out. This is a nice advantage to named functions.
Finally, let's take a look at a third way we could handle it:
$.ajax({
url: 'http://google.com',
success: function(data){
console.log(data);
}
});
Here, we define an anonymous function right inline on the success handler. This works exactly the same as either of the other two options. In all three of these ways, jquery receives a function declaration, and calls it when it needs to, which is after the ajax request has come back.
I know this is a super long answer, but what you are confused about here are some of the core concepts of javascript, and I thought it would be more helpful to go over them here than to just solve your problem and give you the answer without explanation of the concepts. In fact, I haven't actually tackled your problem here at all, but you will easily be able to solve it yourself after understanding these concepts. If you are still having trouble, drop a comment and I'll try to clarify more.
Given the above code, you would call it like this within your submit handler:
var values = '…';
checkDuplicateIndex(values, function(returnValue) {
alert(returnValue);
// additional processing here...
});
I have searched everywhere for a solution to this but have not been able to find anything thus far (I am probably using the wrong keywords! If this is a duplicate, please point out and I will delete).
Could one of you brilliant SO geniuses kindly explain to me why the following does not work as one would hope? What I mean by this is the complete callback is called before the setTimeout has completed within the success callback and I don't quite understand why.
$.ajax({
url: options.url,
data: options.data,
success: function(){
setTimeout(function(){
console.log('firing');
},2000);
},
dataType: options.dataType,
complete: function(){
console.log('ended');
}
});
Is it because a new thread has been started by the setTimeout within the success callback?
Is this possible to achieve without passing in a callback function into the success callback?
It happens because setTimeout() does not block the execution of code.
Therefore the complete callback fires at the same moment as it would without your call to setTimeout().
You will have to put your console.log('ended'); call into a timeout (too) or call your complete handler inside the timeout. :)
Q1) I am using the tootltip from twitter bootstrap. I just noticed that its not working when the contents are added with ajax. After lots of googling, the solution seems to trigger the tooltip after ajax request. But in my case this is not possible because I am relying on the built in ajax API's for the framework. Is there any other work around?
$('.tootip').tooltip({placement:'left'});
Q2) In jQuery on() documentation, the usage is mentioned as
$(document).on(event, selector, function(){ //do stuff here })
So is this I have to do it?
$(document).on('ready', '.tootip', tooltip({placement:'left'}));
But its not working.
A1) One of the options/parameters you give to the ajax call is a callback function that triggered when the ajax call done and succeded. This success callback should initialize the tooltip.
For example, if you are using jQuery:
$.ajax({
url: 'your url'
success: function(result) {
// do your sruff here. Result holds the return data of the ajax call
}
});
A2) Look at the 3'rd parameter: function(){ //do stuff here }. You have to supply a function. Instead, what you have supplied is the result of invoking the function tooltip({placement:'left'}) which in this case returns an object and not a function. You should do:
$(document).on('ready', '.tootip', function() {
$('.tootip').tooltip({placement:'left'});
});
Update regarding your comment:
Inside a function, whether is a success callback or an event function, you can do whatever you like including call multiple functions:
$(document).on('ready', '.tootip', function() {
// Do many operations as much as you like here
func1();
func2();
});
$.ajax({
url: 'your url'
success: function(result) {
// Do many operations as much as you like here
func1();
func2();
}
});
Hope this helps!
Good Morning,
I am trying to call the same function everytime the user presses a button. Here is what happens at the moment..
User clicks button -> Calls function -> function takes 1000ms+ to finish (due to animation with jQuery and AJAX calls)
What I want to happen is every time the user presses the button it adds the function to the queue, waits for the previous call to finish, and then starts..
Is this possible?
Sorry if my explanation is a bit confusing..
Thanks Matthew
Since Functions are objects they can store properties. You can have your function increment a 'queue' property on itself every time its called (button pressed) and then at the end of the function execution, check if the queue property of itself is > 0, and if so, decrement the queue property by one and call itself again using setTimeout.
You could add a callback function to the one that makes the animation, once the animation finishes the callback it's called so you can do what you want.
Here follows an example from the jquery docs:
$('#clickme').click(function() {
$('#book').animate({
opacity: 0.25,
left: '+=50',
height: 'toggle'
}, 5000, function() {
// Put your code here, so it will be executed once the animation completes
});
});
P.S.: Morning? It's almost midnight ;D
You could keep track of a global queue/array where you add to the queue each time the user presses the button, then you'll want a callback in your function (such as in the success callback for jQuery) that does the work to check the queue and call the next function on the queue.
I recently had to do this in my own application. The best suggestion I have for you is (assuming you already have your AJAX calls inside of a JavaScript function) to pass a callback function parameter into your JavaScript function. Then, in the success section of your AJAX call, call your callback function.
Example:
// In HTML <script> tags.
$(document).ready(function () {
$("button#queue").click(function() {
GetMembers(GetGroups(), MemberCallback));
});
});
function GetMembers(userId, callback) {
$.ajax({
//Initialized AJAX properties
url: "/My/Project/Ajax/Page.extension",
data: "{ 'groupId':'" + groupId + "'}",
success: function (result) {
callback(result.d);
}
});
}
function MemberCallback(members) {
// Do your thing here.
}
Disable the button when they click it. Enable it when the ajax routine is complete.
Is there a way to listen for a javascript function to exit? A trigger that could be setup when a function has completed?
I am attempting to use a user interface obfuscation technique (BlockUI) while an AJAX object is retrieving data from the DB, but the function doesn't necessarily execute last, even if you put it at the end of the function call.
Example:
function doStuff() {
blockUI();
ajaxCall();
unblockUI();
};
Is there a way for doStuff to listen for ajaxCall to complete, before firing the unBlockUI? As it is, it processes the function linearly, calling each object in order, then a separate thread is spawned to complete each one. So, though my AJAX call might take 10-15 seconds to complete, I am only blocking the user for just a split-second, due to the linear execution of the function.
There are less elegant ways around this...putting a loop to end only when a return value set by the AJAX function is set to true, or something of that nature. But that seems unnecessarily complicated and inefficient.
However you're accomplishing your Ajax routines, what you need is a "callback" function that will run once it's complete:
function ajaxCall(callback){
//do ajax stuff...
callback();
}
Then:
function doStuff(){
blockUI();
ajaxCall(unblockUI);
}
Your AJAX call should specify a callback function. You can call the unblockUI from within the callback.
SAJAX is a simple AJAX library that has more help on how to do AJAX calls.
There's also another post that describes what you're looking for.
You can do a synchronous xhr. This would cause the entire UI block for the duration of the call (no matter how long it might take).
You need to redesign your program flow to be compatible with asynchronus flow, like specifying a callback function to be called after the response is processed. Check out how Prototype or JQuery or ... accomplishes this.
The answer is simple, you have to call unblockUI() when your ajax request returns the result, using jQuery you can do it like this:
function doStuff(){
blockUI();
jQuery.ajax({
url: "example.com",
type: "POST", //you can use GET or POST
success: function(){
unblockUI();
}
});
}
It sounds to me that you want the user to wait while info is being fetched from the db. What I do when I make an Ajax call for some info from the database is to display an animated gif that says "getting it..." - it flashes continually until the info is retrieved and displayed in the webpage. When the info is displayed, the animated gif is turned off/hidden and the focus is moved to the new info being displayed. The animated gif lets the user know that something is happening.