I am not writing a plugin. I am just looking for a simple clean way to let myself know when a certain function has finished executing ajax calls or whatever.
So I have this:
function doSomething() {
...
getCauses("", query, function () {
alert('test');
});
...
}
function getCauses(value, query) {
//do stuff...
}
Of course the alert never happens. I have a $.ajax call inside getCauses and would like to alert or do some action after getCauses finishes executing and then running the line of code from where the function was called.
Ideas? Thanks.
You first need to add the parameter to getCauses:
function getCauses(value, query, callback) {
}
Then, inside of your $.ajax call, call the callback parameter in your AJAX completion callback:
$.ajax({
// ...
complete: function() {
// Your completion code
callback();
}
});
You're passing your callback function but not executing it.
function doSomething() {
...
getCauses("", query, function () {
alert('test');
});
...
}
function getCauses(value, query, callback) {
//do stuff...
//stuff is done
callback();
}
Just using a bit of javascript trickery, here's an implementation that will allow you to implement some default functionality, in the case that no callback is defined. This would be great if 99% of the time you want a generic callback, and then you simply want to customize it in a few places.
var my_callback = function() {
alert('I am coming from the custom callback!');
}
var special_function(string_1, callback) {
(callback || function() {
// Default actions here
alert('I am coming from the generic callback');
})();
}
// This will alert "I am coming from the custom callback!"
special_function("Some text here", my_callback);
// This will alert "I am coming from the generic callback"
special_function("Some text here");
// This will do nothing
special_function("Some text here", function() {});
Cheers!
Related
function make(callback) {
//some other manipulation to get data to pass it into $.post()
$.post(data, function(response) {
// do something
callback()
});
}
function two() {
make(function() {
console.log('hello');
});
}
console.log('hello') will still trigger first although I used callback. How to make make() run till everything is finished then trigger console.log('hello')?
Your code should work as soon as you call two().
This might visualize your situation better:
function requestSomething(callback) {
$.post(data, function(response) {
// do something
callback();
});
}
function callBackFunction() {
console.log('done!');
}
// Pass callBackFunction, which gets called after request.
requestSomething(callBackFunction);
I am writing a function that makes a http call to a web service, grabs some data and calls another function based on this data. If the service is down, the second function should not be called. I thought the obvious way to do this would be to write $.when(func1()).done(func2); but this will trigger func2 even when the request is aborted. I realise that I can do a workaround by calling func2 within the success function of func1's $.getJSON method, but I would like to use the deferred syntax if possible. Can anyone suggest how to handle this in a way that is consistent with the deferred object syntax?
function checker() {
console.log("in checker");
$.getJSON("http://djdjdjdjdjinvalidUrl.dkdkdk", function(data) {
console.log("in success function");
});
}
function crosser(data) {
console.log("in crosser");
}
$(document).ready(function(){
$.when(checker()).done(crosser);
});
See jsFiddle for a live example.
you need to return a promise from checker
function checker() {
console.log("in checker");
return $.getJSON("http://djdjdjdjdjinvalidUrl.dkdkdk", function(data) {
console.log("in success function");
});
}
Demo: Fiddle
Also there is no need to use $.when()
$(document).ready(function(){
checker().done(crosser);
});
Demo: Fiddle
For asynchronous events like $.getJSON, you need to use the actual deferred object. I've updated your jsfiddle with this object in use: http://jsfiddle.net/wM7aP/1/
Code:
function checker() {
var dfd = new jQuery.Deferred();
console.log("in checker");
$.getJSON("http://djdjdjdjdjinvalidUrl.dkdkdk", function(data) {
//handle data here
dfd.resolve( "hurray" );
});
return dfd.promise();
}
function crosser(data) {
console.log("in crosser");
}
$(document).ready(function(){
$.when(checker()).done(crosser);
});
Why is this code working:
function onCordovaReady() {
navigator.globalization.getLocaleName(function (locale) {
jQuery.i18n.properties({
name:'message',
path:'lang/',
mode:'map',
language:locale.value,
callback: function(){
alert(locale.value);
alert(jQuery.i18n.prop('msg_hello'));
alert(jQuery.i18n.prop('msg_complex', 'John'));
}
});
});
}
And this one not:
function onCordovaReady() {
navigator.globalization.getLocaleName(function (locale) {
jQuery.i18n.properties({
name:'message',
path:'lang/',
mode:'map',
language:locale.value,
callback: onLanguageReady(locale)
});
});
}
function onLanguageReady(locale) {
alert(locale.value);
alert(jQuery.i18n.prop('msg_hello'));
alert(jQuery.i18n.prop('msg_complex', 'John'));
}
I want to make the callback in a different function so my code will look cleaner, but couldn't get it to work. The first alert will work (it will display nl_NL), but the second and third alert will output [msg_hello] and [msg_complex].
Many thanks!
Try with this:
// beginning of code omitted
callback: function(locale) {
onLanguageReady(locale)
}
it is because you are assigning undefined to the callback property.
You are calling onLanguageReady and assigns that value to the callback method.
The solution is to use another function as callback function which will call the onLanguageReady function as given by #romainberger
function onCordovaReady() {
navigator.globalization.getLocaleName(function (locale) {
jQuery.i18n.properties({
name:'message',
path:'lang/',
mode:'map',
language:locale.value,
callback: onLanguageReady
});
});
}
function onLanguageReady(locale) {
alert(locale.value);
alert(jQuery.i18n.prop('msg_hello'));
alert(jQuery.i18n.prop('msg_complex', 'John'));
}
will work if the function calls back with locale.
the callback is expecting a function pointer that it can call once the processing is done when you say onLanguageReady(locale) you are actually executing the function and thus assigning the result of the function as the call back in this case the return is nothing thus undefined
So let's say I'm calling a function like so:
some_function('pages',{attr1: 1, attr2: 2},function(){
alert('the function is ready!');
}
Now how do I set up the "some_function()" function in order to return to the caller that it is ready and make the alert go off?
Thanks :)
I think you mean callbacks.
Maybe something like this:
function some_function(param1, param2, callback) {
// normal code here...
if ( typeof callback === 'function' ) { // make sure it is a function or it will throw an error
callback();
}
}
Usage:
some_function("hi", "hello", function () {
alert("Done!");
});
/* This will do whatever your function needs to do and then,
when it is finished, alert "Done!" */
Note: Put your return after the if clause.
Do you mean something like this?
function some_function(type, options, callback) {
if (some_condition) {
callback();
}
}
Assuming the signature for some_function looks like this:
function some_function(name, data, callback)
You just need to call callback when you're ready to.
function some_function(name, data, callback){
// do whatever
if(typeof callback === 'function'){
callback(); // call when ready
}
}
I need to execute a specific function mvFinishItUp() when two conditions are met. More specifically, one condition is the callback success of a $.ajax the other is a normal flow of the code until it reaches the function. Kinda of this:
$.ajax({
url: mv_finalUrl,
success: function (data) {
mvFinishItUp(data);
},
dataType: 'html'
});
/* here a lot more code, with animations and some delays */
mvFinishItUp(data) {
/* My function code */
/* But this code must only run after it has been called via the call back
and after all the other code has been ran as well */
}
So, the function must wait for all the code if the ajax callback is quicker, or the other way around. Any ideas on how this could be implemented?
I'm willing to change the whole concept of script code, as I believe the loose code between the ajax, and the function itself should go to a function aswell ...
This is a perfect use case for jQuery Deferred objects.
Remove the success: parameter from the AJAX call, and register the handler later:
var jqxhr = $.ajax(...);
// do some other synchronous stuff
...
// and *then* register the callback
jqxhr.done(mvFinishItUp);
Deferred objects cope perfectly well (by design) with being registered on an AJAX event after that event already finished.
Try like below, (It is just psuedo code)
var isAJAXDone = false, isFunctionCodeDone = false;
$.ajax({
//..
success: function () {
isAJAXDone = true;
mvFinishItUp(data, isAJAXDone, isFunctionCodeDone);
}
});
//..Your function code
//..Add this below the last line before the function ends
isFunctionCodeDone = true;
mvFinishItUp(data, isAJAXDone, isFunctionCodeDone);
//..
mvFinishItUp(data, isAJAXDone, isFunctionCodeDone ) {
if (isAJAXDone && isFunctionCodeDone) {
//Do your magic
}
}
Maybe something like this would do the trick:
var _data = undefined;
$.ajax({
url: mv_finalUrl,
success: function (data) {
_data = data;
myFinishItUp(data); // call the function from here if it's faster
},
dataType: 'html'
});
/* here a lot more code, with animations and some delays */
function myFinishItUp(data) {
this.data = data; // store the data from the AJAX call or the code, whichever reaches first
// if the code reaches this before the AJAX call completes, data will be undefined
if(typeof this.wasCalled == "undefined") {
/* My function code */
/* But this code must only run after it has been called via the call back
and after all the other code has been ran as well */
this.wasCalled = true;
}
}(_data); // function that calls itself when the code gets to this point with a self-contained boolean variable to keep track of whether it has already been called
I used a self calling function execute when the code flow gets to that point, but if it's called from the AJAX call, it won't execute. It keeps track of whether or not it's already been called with a self-contained boolean value.
Here I add an second parameter to check callback check
function mvFinishItUp(data, byCallback) {
var iscallback = byCallback || false; // if you don't send byCallback
// default will false
if(iscallback) {
// execute if called by callback
}
}
success: function (data) {
mvFinishItUp(data, true); // call with second parameter true
},
To execute mvFinishItUp() after ajax done and all codes between ajax and mvFinishItUp finished you can do something like this:
var allFunctionExecuted = false; // global to detect all code execution
$.ajax({
url: mv_finalUrl,
success: function (data) {
mvFinishItUp(data, true);
},
dataType: 'html'
});
function func1() {
}
function func2() {
}
// some other code
function func3() {
allFunctionExecuted = true;
}
Now,
function mvFinishItUp(data, byCallback) {
var iscallback = byCallback || false; // if you don't send byCallback
// default will false
if(iscallback && allFunctionExecuted) {
// execute if ajax done
// and others code done
}
}
This is very "ugly" code, but you can modify it to not use global vars, so this is just illustrative:
var ajaxExecuted = false,
codeExecuted = false;
$.ajax({
url: mv_finalUrl,
success: function (data) {
ajaxExecuted = true;
mvFinishItUp(data);
},
dataType: 'html'
});
/* here a lot more code, with animations and some delays */
codeExecuted = true;
mvFinishItUp(data) {
/* My function code */
if(ajaxExecuted && codeExecuted) {
/* But this code must only run after it has been called via the call back
and after all the other code has been ran as well */
}
}
I just added two flags: ajaxExecuted and codeExecuted, and inside the function an if statement that checks the value of the those flags, and executes only when the two of them are set to true. So no mather who calls it first, it get only executed when the two flags are set to true.
A cleaner way could be to implement the function in an object, and use properties instead of global vars.