I have 2 functions: 1 checks that the user is logged in, and if he does - it calls for second function to get his userID. For now I'm just testing it with alert, to see if I do get the parameter.
This is the first function:
//Checking if the user is logged in or not
$(function(){
$.getJSON("inc/API.php", {command : "getUserName"},
function(result){
if(result==null){
$("#divGreeting").html("Hello, guest!");
$("#divLogin").hide();
$("#divUserOption").hide();
$("#divConnectOption").show();
}
else {
alert(getUserID(result));
$("#divGreeting").html("Hello, "+result+"!");
$("#divHeader").html("Hello, "+result+"! <a href='javascript:logout()'>Logout</a>");
$("#divUserOption").html("Hello, "+result+"! <a href='javascript:logout()'>Logout</a>");
$("#divConnectOption").hide();
$("#divLogin").hide();
$("#divUserOption").fadeIn(300);
}
});
});
And this is the second function, the one that should return the userID:
function getUserID(){
$.getJSON("inc/API.php",
{
command : "getUserID"
},
function(result){
alert(result);
return result;
});
}
The alert of the first function is undefined, while the alert of the second does have the userID. How come I can't return it's value to the first function? Why do I get `undefined?
Thank you!`
Ajax is asynchronous. You can't return a value from it.
What are are trying to do is akin to:
function foo() {
$('button').click(function () { return 1; });
}
var not_one = foo();
In this example, the value is not returned until the button is clicked (and it isn't the return value of foo anyway). With Ajax, the value is not returned until the HTTP response arrives.
You have to process the data in the callback function and not try to return to the calling function.
Try this:
//Checking if the user is logged in or not
$(function(){
$.getJSON("inc/API.php", {command : "getUserName"},
function(result){
if(result==null){
$("#divGreeting").html("Hello, guest!");
$("#divLogin").hide();
$("#divUserOption").hide();
$("#divConnectOption").show();
}
else {
getUserID(function(result) {
$("#divGreeting").html("Hello, "+result+"!");
$("#divHeader").html("Hello, "+result+"! <a href='javascript:logout()'>Logout</a>");
$("#divUserOption").html("Hello, "+result+"! <a href='javascript:logout()'>Logout</a>");
$("#divConnectOption").hide();
$("#divLogin").hide();
$("#divUserOption").fadeIn(300);
});
}
});
});
and then your getUserID function:
function getUserID(callback){
$.getJSON("inc/API.php",
{
command : "getUserID"
},
callback
}
EDIT
You said that you would need to use the username in a string concatenation context :
"Hello "+getUserName()+"!"
however, if it has to make an AJAX request every time, this is not possible unless a blocking,syncronous call is being used which is not a good practice at all. If you store the username in a variable when the page loads, you can just use the variable. if you want to still use a function that requests it every time it's used, it would have to be done something like this:
function getUserName(callback) {
$.getJSON("inc/API.php", {command : "getUserName"}, callback);
}
getUserName(function(result){
//do username processing here
});
Related
In specific, I'm making a call to the database which retrieves an aggregate value. This is then displayed to the user. But before the adapter call(since I'm using worklight) can complete,the code after that gets executed which is something that I want to block. I have tried everything from setTimeout to calling a function that executes an empty while loop. None of them seem to work as the code is skipping all of these too. Could someone please help me out with this?
Sample code:
var flow_completed_percentage=0;
function setFlowStatus()
{
var flow_name,flow_status_value;
for(var i = 0;i < 2; i++)
{
flow_name=flow_name_DB[i].trim();//flow_name_DB is an array that stores the flow names
flow_status_value=flow_status_DB[i].trim();//flow_status_DB is an array that stores the flow status values
if(flow_status_value=="R" || flow_status_value=="A")
{
var invocationData_totalPercentage = {
adapter : "dummy_adapter",
procedure : "getJobPercentage",
parameters : [flow_name]
};
WL.Client.invokeProcedure(invocationData_totalPercentage, {
onSuccess : setPercentageSuccess,
onFailure : setPercentageFailure
});
}
}//end of for loop
//the problem is next iteration of for loop begins before the adapter call for the current iteration completes.
//So flow_name gets overwritten and it gives the wrong result.
function setPercentageSuccess(total_percentage)
{
var tot_percent = total_percentage.invocationResult.resultSet[0];
flow_completed_percentage=tot_percent.TOT_PERCENT;
if(flow_status=="R")
runningStatus(flow_name);
else if(flow_status=="A")
abortedStatus(flow_name);
}
function setPercentageFailure()
{
alert("Failed to fetch records from DB");
}
}
function runningStatus(flow)
{
//do something
}
function abortedStatus(flow)
{
//do something
}
You must call the remaining block of code after the completion of you database operation.
Since have to perform the same operation number of times, you can call the function multiple times instead of using a loop.
I tried to change the code as follows: You can call the function with next value of i after the completion of database operation.
var flow_completed_percentage=0;
function setFlowStatus()
{
var flow_name,flow_status_value;
var initial = 0;
iterator(initial); // initial call
function iterator(i)
{
flow_name=flow_name_DB[i].trim();//flow_name_DB is an array that stores the flow names
flow_status_value=flow_status_DB[i].trim();//flow_status_DB is an array that stores the flow status values
if(flow_status_value=="R" || flow_status_value=="A")
{
var invocationData_totalPercentage = {
adapter : "dummy_adapter",
procedure : "getJobPercentage",
parameters : [flow_name]
};
WL.Client.invokeProcedure(invocationData_totalPercentage, {
onSuccess : function() {
setPercentageSuccess();
iterateNext(i); // call next after DB completion
},
onFailure : function() {
setPercentageFailure();
iterateNext(i); // call next after DB completion
}
});
}
}
function iterateNext(current)
{
current= current+1;
if(current<2){ // check the loop condition
iterator(current);
}
}
function setPercentageSuccess(total_percentage)
{
var tot_percent = total_percentage.invocationResult.resultSet[0];
flow_completed_percentage=tot_percent.TOT_PERCENT;
if(flow_status=="R")
runningStatus(flow_name);
else if(flow_status=="A")
abortedStatus(flow_name);
}
function setPercentageFailure()
{
alert("Failed to fetch records from DB");
}
}
function runningStatus(flow)
{
//do something
}
function abortedStatus(flow)
{
//do something
}
So I am using POST to get data, in this case the variable lotSize, from a server side script. I also have a function called doSomething, which takes lotSize as an argument. However, I want doSomething to execute only when I click a button. I cannot figure out how to do this. Can anyone help?
def doSomething(sqFootage){
//stuff to do
}
//this post sends address information to a server side script,
//which returns the variable lotSize
$.post(
"/demo.php",
{
pAddress: streetAddress,
pCity: city,
pState: state,
pZip: zipCode
},
function(lotSize) {
event.preventDefault();
//I want this function to only execute on a certain onclick
doSomething(lotSize);
});
Is this all you want to do?
$('#IdOfYourButton').click(function(e){
e.preventDefault();
$.post(
"/demo.php",
{
pAddress: streetAddress,
pCity: city,
pState: state,
pZip: zipCode
},
function(lotSize) {
event.preventDefault();
doSomething(lotSize);
});
});
See step 1 to 3
// step 1) Put a global variable here, let's call it x
def doSomething(sqFootage){
//stuff to do
}
//this post sends address information to a server side script,
//which returns the variable lotSize
$.post(
"/demo.php",
{
pAddress: streetAddress,
pCity: city,
pState: state,
pZip: zipCode
},
function(lotSize) {
event.preventDefault();
//I want this function to only execute on a certain onclick
//doSomething(lotSize);
// step 2) Assign lotSize to the global variable x from step 1
});
// step 3) Create the onclick event handler here and call doSomething(x); where x is the global variable that contains the value from lotSize
Has anyone found that their javascript doesnt work, but when they step through the code it works fine ?
var cookie = getCookie('lusr');
var username = cookie;
if(!cookie){
$("#UserNav").load("loginform.html");
$("#loginbtn").click( function(){
var username = $("#usernametxt").val();
var password = $("#passwordtxt").val();
login(username,password);
});
}else{
$("#UserNav").load("user.htm");
$("#WelcomeUser").text("Welcome "+ username);
}
My issue occurs on this line :
$("#WelcomeUser").text("Welcome "+ username);
That's because load() is asynchronous: it returns right away, performs its work in the background, then calls a user-provided function when its task is complete. The stepping delay gives you the illusion that the function is synchronous and performs all its work before returning.
Therefore, you should pass a callback function to load() and perform your subsequent work inside that callback:
var cookie = getCookie("lusr");
if(!cookie) {
$("#UserNav").load("loginform.html", function() {
$("#loginbtn").click(function() {
var username = $("#usernametxt").val();
var password = $("#passwordtxt").val();
login(username, password);
});
});
} else {
$("#UserNav").load("user.htm", function() {
$("#WelcomeUser").text("Welcome " + cookie);
});
}
You are using the load() function which asynchronously fetches from the server. This means your form has not loaded by the time you go searching for its fields.
The reason it works when you step through is because it gives it time to load the form while you step.
You can use another version of load which has an asynchonous callback function, allowing you to provide functionality only to be called once the load is complete.
Check the jQuery docs for more info.
I have a page which clients sometimes leave open for extended periods of time without refreshing (over 24hrs). Some of the actions on that page require valid PHP session so I have built a simple set of functions to run this check every 10 minutes.
2 Functions:
checkLogin()
refreshTimer()
We call checkLogin() to start, checkLogin() calls refreshTimer(). After timer completes it should call checkLogin(), which should call refreshTimer() and start the process all over again.
The first time we call checkLogin() directly things works great. However, when refreshTimer() tries to call checkLogin() I get a "function not defined" error for checkLogin().
From my research it looks like I should be able to call the checkLogin() without passing it to the refreshTimer().
I'm sure I'm probably missing something obvious. Thanks for your help!
function checkLogin()
{
$.ajax({
url: "/mysite.com/dev/includes/check_login_helper.php",
success: function(logged_in)
{
if(logged_in == "false")
{
// they are logged out - redirect them to login page
alert("logged out");
}
}
});
refreshTimer();
}
function refreshTimer()
{
var t = setTimeout("checkLogin()",15000); // do each 10 min currently shorter for test
}
//start the process up
checkLogin();
Fixed & using checkInterval
function checkLogin()
{
$.ajax({
url: "/mysite.com/dev/includes/check_login_helper.php",
success: function(logged_in)
{
if(logged_in == "false")
{
// they are logged out - redirect them to login page
alert("logged out");
}
}
});
}
setInterval(checkLogin(),15000); // do each 10 min currently shorter for test
Don't pass a string to setTimeout; it'seval in disguise. There is also no reason to capture the value returned by setTimeout in this case.
function refreshTimer()
{
setTimeout(checkLogin, 15000);
}
var t = setTimeout("checkLogin()",15000);
needs to be
var t = setTimeout(checkLogin,15000);
this method accepts functions and not strings.
I'm writing a callback function for the FB.Connect.showPermissionDialog() function which accepts permissions and an optional callback function.
It's supposed to be passed null if the user rejects the permissions dialog. But for some reason, my script always makes the post request even if the permissions request failed.
echo("FB.ensureInit ( function () {
FB.Connect.showPermissionDialog('email,offline_access',
function(accepted) {
if(accepted==null) {alert('failure');} else {
$.post(\"http://www.domain.com/permissions.php\",
{ username:$userID,mode:'accepted'});}
});
});");
Not sure why it's not reading the value of accepted properly. Thanks for the help.
My first guess is that the Javascript null value is not actually being returned, and some other false-like value is being returned instead.
I'd try changing to this to test for all false-like values:
if (!accepted) {alert('failure')} else {
...
Do with firebug:
console.log(accepted)
And see what you're getting back. Could be undefined, which according to your logic still passes.
Maybe you should change your logic around:
echo("FB.ensureInit ( function () {
FB.Connect.showPermissionDialog('email,offline_access',
function(accepted) {
if(accepted !== null) {
$.post(\"http://www.domain.com/permissions.php\",
{ username:$userID,mode:'accepted'});}
} else {alert('failure');}
});
});
");