I've a javascript method defined as follows:
updtCrtEdtPage = function() {PrimeFaces.ab({source:'j_id_ev',formId:'j_id_es',process:'typeNewLOB_in lobIdForEdit j_id_ev',update:'createLOBFullPagePanel',oncomplete:function(xhr,status,args){prepareForCrtEdtFullPage();},params:arguments[0]});}
I want to execute certain method (afterComplete()) whenever this method has finished executing. (This method actually initiates an ajax request & appends the received HTML data on the DOM). So I want my afterComplete() method to be executed whenever ajax response has been received.
I cannot directly do like:
updtCrtEdtPage();
afterComplete();
as this would call the afterComplete() soon after ajax request is initiated & not completely finished executing yet.
Is there any JS/ jQuery way I could do that ?
You could pass afterComplete as a parameter so your function can call it when the ajax call is complete. Something like this...
updtCrtEdtPage = function(callback) {
PrimeFaces.ab({
source:'j_id_ev',
formId:'j_id_es',
process:'typeNewLOB_in lobIdForEdit j_id_ev',
update:'createLOBFullPagePanel',
oncomplete:function(xhr,status,args){
prepareForCrtEdtFullPage();
callback();
},
params:arguments[0]
});
}
updtCrtEdtPage(afterComplete);
Since you say you can't modify updtCrtEdtPage, but you can modify prepareForCrtEdtFullPage I'd suggest using a global variable to determine which callback function to call when the method is complete...
updtCrtEdtPageCallback = afterComplete;
and then in prepareForCrtEdtFullPage just add the last line...
updtCrtEdtPageCallback();
The first method is tidier, but the second will suffice for your particular situation.
your updtCrtEdtPage = function() has an oncomplete callback which is called when the ajax response has been received, add your afterComplete function in that callback and it will execute after the ajax request has been completed.
oncomplete:function(xhr,status,args){
prepareForCrtEdtFullPage();
afterComplete()
}
Related
Okay so look at these to alert()s. Here is the full code:
function OfficialFacebookLikes(Title)
{
$.getJSON('https://graph.facebook.com/'+Title, function(data) {
alert(data['likes'].toString()); //<<temp
return data['likes'].toString();
});
}
$(document).ready(function(){
$('.ui-btn').click(function(){ //cocacola
var LikeCount = OfficialFacebookLikes("cocacola");
alert(LikeCount);
});
});
Why does
alert(LikeCount)
display (which is "undefined" when displayed) before
alert(data['likes'].toString())
I called the function OfficialFacebookLikes before I called the alert(LikeCount). Could someone please explain why this is occurring. If my thought process isn't making since.. I'm use to coding in C++.
This is an asynchronous Ajax call. You won't have data available until the call returns. In your document ready code, you are attempting to alert the call immediately.
Instead, do whatever you need to do with the result set in the callback handler of the ajax:
$.getJSON('https://graph.facebook.com/'+Title, function(data) {
doSomethingWithMy(data);
});
The .getJSON function is asynchronous, this means that it needs a callback to call when it's finished, otherwise you'll never know when the function has been completed. Asynchronous functions run separately from the rest of the code.
When you call OfficialFacebookLikes("cocacola") it will call the .getJSON function. Now the .getJSON functions starts by its own and doesn't stop the script, so right after calling OfficialFacebookLikes("cocacola"), the next line of code is executed, which is actually alert(LikeCount). But LikeCount has not yet been defined, since that .getJSON is still working.
When .getJSON finishes working the callback function given in $.getJSON(..., function() {... }) gets executed, and then the LikeCount variable gets defined. So if you want to alert LikeCount you have to put the alert() inside the callback of .getJSON.
Imagine this scenario:
I have a link that fires up a JavaScript function(has an Ajax request in it).
The JavaScript function has a parameter passed by the link's onclick='jsFunction(param)'.
The JavaScript function sends the parameter value in a function inside a controller that sets the param value to a session variable.
The function in the controller will then send the new value of the session variable back to the JavaScript function's Ajax request.
When the data reached into the Ajax request, another function will be called using the data being passed.
Question:
Since I am talking about the session variable's value being passed to an Ajax request, how can I process the data came from the link to the second function in real-time? I want to post the code here but it's too verbose with the info I only need.
The current state of my code is that, I can't fetch the right/latest data. Instead, I get the previous data came from the previous link I clicked.
Is there an Ajax feature that I can only proceed to the next function if the first function is done processing the latest data?
Any help will be much appreciated.
You can use the callback to any of the jQuery AJAX methods to delay execution of another function until after the request is complete.
$.post('/some/url', somedata, function(returnData) {
// put the code you want to execute on completion here
});
or If you have already defined your function to be called after returning data, you can just write like this:
$.post('/some/url', somedata, processData);
I have 2 javascript functions, the first being a function which loads ajax content (via another function), and a second which is a callback function. They look like:
function createReply(callBack){
ajaxPage('test.html', 'next-reply');
callBack();
}
function updateNext(){
document.getElementById('next-reply').id = "reply-item";
}
createReply(updateNext);
As you can see, I am calling the createReply() function and passing it the name of the callback function, in this case updateNext()
In the createReply() function, I am calling another function which loads content via ajax. When this function is complete, the callback is supposed to be executed. The callback changes the id of the div in which the ajax content is being loaded. This is where the problem is occuring
I am getting the error:
Uncaught TypeError: Cannot set property 'innerHTML' of null
Which is saying that it cannot change the content of the element with the id "next-reply" because it doesn't exist, and the reason it doesn't exist is because the callback function changes the id if that element. The intention is to have the callback fire after the ajax content has been loaded (ie; after the ajaxPage() function has been executed)
Can anyone see what the problem is? Is there a better way of implementing a callback function in plain javascript?
PS: no jQuery
As pointed out in the comments, this is due to the fact that AJAX calls happen asynchronously. The thread that createReply runs in continues to run before a response is returned from the server.
You'll need to re-factor ajaxPage to accept a reference to callback, and call it when the response is ready. Something like:
function createReply(callBack){
ajaxPage('test.html', 'next-reply', callBack);
}
Then, in ajaxPage:
function ajaxPage(url, id, callback){
//Do AJAX stuff
//When the response is returned:
if(callback) callback();
}
Right now you callback is executed right after the ajaxPage function. By right after I mean you do not wait for ajaxPage to return success. It is fired right after the ajax call goes out. It is very likely that it is not completed before your callback is fired.
I add a click event handler to an element
$(".elem").click(function(){
$.post("page.php".function(){
//code1
})
})
And then I trigger a click event
$(".elem").click();
//code2
How can i make sure that code2 executes after code1 executes
(Ignoring WebWorkers) JavaScript runs on a single thread, so you can be sure that code2 will always execute after code1.
Unless your code1 does something asynchronous like an Ajax call or a setTimeout(), in which case the triggered click handler will complete, then code2 will execute, then (eventually) the callback from the Ajax call (or setTimeout(), or whatever) will run.
EDIT: For your updated question, code2 will always execute before code1, because as I said above an async Ajax callback will happen later (even if the Ajax response is very fast, it won't call the callback until the current JS finishes).
"How i make sure that code2 executes after code1 executes"
Using .click() with no params is a shortcut to .trigger("click"), but if you actually call .trigger() explicitly you can provide additional parameters that will be passed to the handler, which lets you do this:
$(".elem").click(function(e, callback) {
$.post("page.php".function(){
//code1
if (typeof callback === "function")
callback();
});
});
$(".elem").trigger("click", function() {
// code 2 here
});
That is, within the click handler test whether a function has been passed in the callback parameter and if so call it. This means when the event occurs "naturally" there will be no callback, but when you trigger it programmatically and pass a function then that function will be executed. (Note that the parameter you pass with .trigger() doesn't have to be a function, it can be any type of data and you can pass more than one parameter, but for this purpose we want a function. See the .trigger() doco for more info.)
Demo: http://jsfiddle.net/nnnnnn/ZbRJ7/1/
You can try writing this way:
$(".elem").live("click", function(){
//code1
})
// for newer jquery version from 1.9
$(".elem").on("click", function(){
//code1
})
And, your trigger will always execute as fired.
Wrap code2 in method and add it as a callback inside code1 so it will always get called after code1 executes
code2 = function(){/*code2*/};
$(".elem").click(function(){
//code1
code2();
})
Javascript execution is line by line. So whatever comes up, will be executed first. So adding the click code before the other method will work.
Plus if there is any async call, then take a flag which is set only when you get response.
var clicked = false;
$('#elem').click(function(){
// do some async process
clicked = true;
});
while (!clicked){ // do nothing }
// other function to be called
Or the second option will be, if using post method, set async = true in property.
I'd like to fire a JavaScript function when AJAX returns the values of drop down items.
The scenario is:
function 1 fires -> ajax gets items from database -> the dropdown items are filles -> my javascript function is called.
Does any of you have idea how to make a handler for such event ?
As you've tagged the question with jQuery, I'll show you a jQuery solution:
$.post("someScript.php", function(data) {
/*This callback function is executed when the AJAX call returns successfully
You would do something with your dropdown items here
and then call your next function.*/
});
The various jQuery AJAX methods (post, get, load for example) all provide a way to pass a callback as an argument. The callback is executed upon a successful response from the server. Inside that callback function you can execute whatever code you need to, to deal with data which contains the response.
If you're not using jQuery, I'll assume you already have an XMLHttpRequest object. XMLHttpRequest has a property called onreadystatechange to which you can assign a function that runs when the state changes:
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
//This will be reached if the call returns successfully
}
}
The idea is the same as the jQuery method shown above.