0

I've got some javascript that checks over an html form for whatever issues there are that need to be corrected. However, the part that makes an ajax request back to a php script to check the database for presence of username doesn't work.
The php script queries the database and echoes back either "true" or "false". The javascript function with the ajax request looks like this:

function checkUsername()
{
var username = document.getElementById("d_username");
var usernameValue = username.value;
var result;
var xmlhttp;
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    result=xmlhttp.responseText;
    if(result.trim() === "true"){
    return true;    
    }else if(result.trim() === "false"){
    return false;
    }
    }
}
xmlhttp.open("GET","scripts/checkUsername.php?username="+usernameValue,true);
xmlhttp.send();
}

The function that calls this calls a few other functions and does several checks on it's own. However, the part that call this function looks like this:

var check = checkUsername();
if(check===true){
messageText=messageText+"- Username already exists in system.<br />";
status = "fail";
}

However, I was originally using the function name right in the if statement like:

    if(checkUsername()==true)

and if(checkUsername()=="true") plus many variations of ==s, ===s, ''s, ""s, all about the checkUsername() function and where it's called.

Could somebody please help me with why this isn't working.. I just want the function to be able to see if the php script returns true or false and then report either true or false respectively, then for the code that checks if it's true or false to act accordingly. Any help would be greatly appreciated!

  • 1
    The `onreadystatechange` function does not return its value to the function you called. It happens asynchronously. – Lee Meador Sep 16 '13 at 21:55
  • (1) If PHP returns `true` or `false` (booleans, not strings), they'll become `"1"` and `""` in the response. (2) You can't return from an asynchronous operation, as the comment above says. For details, see http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call. – bfavaretto Sep 16 '13 at 21:56
  • Welcome to the wonderful world of **async**! You need a callback or promise. – SLaks Sep 16 '13 at 21:56

3 Answers3

0

Assuming your code is not throwing errors, you have to take into account that Javascript will make a request an continue on with the code. When the response comes back, it will jump back and handle the response how you have dictated.

Try this:

if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
    result=xmlhttp.responseText;
    if(result.trim() === "true"){
        alert(1);    
    }else if(result.trim() === "false"){
        alert(0); 
    }
}

You will be able to see if the code is functioning correctly and debug your PHP file if there are errors. The next thing you would need to do is include the code to change the messageText or other variables globally or with a callback function so the changes show.

Tim Withers
  • 12,072
  • 5
  • 43
  • 67
0

The problem is that the AJAX call you're doing is asynchronous, so your function will exit before the call is done and will return undefined

try:

xmlhttp.open("GET","scripts/checkUsername.php?username="+usernameValue, false);

instead

xmlhttp.open("GET","scripts/checkUsername.php?username="+usernameValue, true);

to make the call synchronous.

Also, you'll have to set a value inside onreadystatechange and return that in your function.

i.e.

var ret_val;

onreadystatechange: ret_val=false instead return false and ret_val=true instead return true

then return ret_val at the end of your function

ryuusenshi
  • 1,976
  • 13
  • 15
  • Great! This worked wonders. I really appreciate it! – include 'breakDance' Sep 17 '13 at 00:39
  • Hey, glad it helped. However, you should also read the accepted answer on the question this is a duplicate of. Although the solution presented here works, it could potentially block your script execution while waiting for the response from the server. You might, therefore, opt for a callback – ryuusenshi Sep 17 '13 at 21:34
0

This can appear rather tricky at first to reason about if you aren't familiar with Asynchronous execution, but here is one way to walk though this code. First the function you have defined called checkUsername() does not have any return statement inside it, so any attempt to set something to it's output or to test it's value will always result in an undefined. There is a function inside checkUsername() that doesn't have a name (called an anonymous function or in this case a callback), and it has a return statement (two actually), but if you notice there is no line that actually calls it. There is an assignment and the variable's name is the only clue as to when this function will run. xmlhttp.onreadystatechange. What this is telling you is that when the Ready State of xmlhttp changes that it should execute this function. Now JavaScript will do this, but if you are reading though this function, you can see that the ready state won't change until after you call the .send() function on xmlhttp, and if you consider that it will take a moment for a network request to complete, it actually won't change until after a few moments. The interesting thing is that xmlhttp is asynchronous meaning that it will just happily live on doing what ever you told it to do after the code that brought it into being is finished. So when you are testing the return value of your function with this line if(checkUsername()==true) you aren't testing the xmlhttp ready state change event because it hasn't happened yet.

Now as for what you can do about this, well the clean approach would be to put the code that depends on this value arriving inside your callback. If you want to step more gracefully into this, you can take a look at jQuery which makes this code a lot easier to reason about. In no time you will be working with Maybe monads and wondering why you wanted events to block :)

Jason Sperske
  • 29,816
  • 8
  • 73
  • 124
  • It's been a long time since I used any javascript. Thanks a lot for this answer, it clarified and reminded me of some stuff that I'd have never realized otherwise. – include 'breakDance' Sep 17 '13 at 00:41