2

I can't seem to figure out how to get this function working. The crucial thing to see is that the tStat = xmlhttp2.responseText seems to be delayed. I have it test this out with the .innerHTML +=" withintest "+Stat. It prints out "withintest withintest withintest 0". So it does a few iterations until it has the value?? 0 is the value of Stat that I want, and the checktStatus.php gets it from a database.

But since this function returns a value, and I have it being called from another function into a variable for that value, it can't be delayed DB read before it returns. But I can't figure out how to accomplish this! Help?

EDIT: took out some commented code, but the problem still remains. It returns an "undefined" value before it can get a real one.

function gettStatus()
{
    var tStat;

    if (window.XMLHttpRequest)
    {     // code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp2=new XMLHttpRequest();
    }
    else
    {     // code for IE6, IE5
            xmlhttp2=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp2.onreadystatechange=function()
    {
      if (xmlhttp2.readyState==4 && xmlhttp2.status==200)
        {
            tStat=xmlhttp2.responseText;        

            document.getElementById("txtHint").innerHTML+=" withintest "+tStat;
            return tStat;
        }
    }
    xmlhttp2.open("GET","checktStatus.php?tID=1",true);

    xmlhttp2.send();    
}
fvertk
  • 159
  • 1
  • 12
  • Try to use a js library, like jquery. You will get in a few lines something that it's stable. – machineaddict Feb 13 '12 at 09:53
  • But surely there is a way to make this return only once its received the value for tStat? Even after I have onreadystatechange uncommented out, it still doesn't seem to wait until the response is loaded, it just sends an "undefined" value from the return statement. Argg... – fvertk Feb 13 '12 at 10:39
  • 1
    @user1094790: You cannot return from an Ajax call. It is **asynchronous**. Make `gettStatus` accept a callback and call it inside the `readystatechange` handler, passing the response. Also search here for `javascript return from ajax call`. – Felix Kling Feb 13 '12 at 10:47
  • possible duplicate of [Return value from function with an Ajax call](http://stackoverflow.com/questions/562412/return-value-from-function-with-an-ajax-call) – Felix Kling Feb 13 '12 at 10:48

2 Answers2

7

How onreadystatechange works

onreadystatechange event handler - as the name of the event suggests - is called when the readyState is changed. So you must check for the state and status (as you did in the part you commented).

See more details here: Mozilla Developer Network: AJAX - Getting Started

List of readyState values

From the page referenced above (link to the section):

The full list of the readyState values is as follows:

  • 0 (uninitialized)
  • 1 (loading)
  • 2 (loaded)
  • 3 (interactive)
  • 4 (complete)

Asynchronous nature of AJAX

You should also be aware of the fact, that usually AJAX works asynchronously, so it would be easier for you to just pass callbacks that will be executed once the response is received, like that:

function gettStatus(callback){
    // do something here...
    callback(result); // ...and execute callback passing the result
}

Solution

Thus you should edit your code to look similarly to this (with readyState / status conditions uncommented):

function gettStatus(callback)
{
    var tStat;

    if (window.XMLHttpRequest)
    {     // code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp2=new XMLHttpRequest();
    }
    else
    {     // code for IE6, IE5
            xmlhttp2=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp2.onreadystatechange=function()
    {
        if (xmlhttp2.readyState==4 && xmlhttp2.status==200)
        {
            tStat=xmlhttp2.responseText;        

            document.getElementById("txtHint").innerHTML+=" withintest "+tStat;
            callback(tStat);
        }
    }
    xmlhttp2.open("GET","checktStatus.php?tID=1",true);

    xmlhttp2.send();    
}

and then just use it like that:

gettStatus(function(tStat){
    // tStat here is accessible, use it for further actions
});

instead of using it in the following manner:

var tStat = gettStatus();
// tStat would be available here, if gettStatus() would not involve
// asynchronous requests
Tadeck
  • 132,510
  • 28
  • 152
  • 198
  • Arg, actually I don't know why I had that commented out, but that's not the issue. Once it's uncommented, the code still keeps moving before it returns. I actually have a line of code that goes: – fvertk Feb 13 '12 at 10:32
  • val tStatus = gettStatus(); But it does THAT line before the function returns the value! So it makes tStatus be "undefined". So I need a way to delay this or whatever the proper way to deal with this issue is. – fvertk Feb 13 '12 at 10:33
  • @user1094790: It is because the request is being sent asynchronously (the "A" letter in "AJAX"). You should deal with this using callbacks (pass a function to `gettStatus` to be executed after the request is properly processed). – Tadeck Feb 13 '12 at 10:52
  • So your "solution" is actually not a solution ;) (it somehow suggests that `return tStat;` works). – Felix Kling Feb 13 '12 at 10:58
  • @FelixKling: I have to confirm you are right. I should have spotted that earlier and update my answer. I will do it now, so you can place your feedback, Felix. – Tadeck Feb 13 '12 at 15:15
0

The lines you have commented out serves the purpose of filtering readystates.

/*if (xmlhttp2.readyState==4 && xmlhttp2.status==200)
{*/
    tStat=xmlhttp2.responseText;        
    document.getElementById("txtHint").innerHTML+=" withintest "+tStat;
    return tStat;
//}

Should be

if (xmlhttp2.readyState==4 && xmlhttp2.status==200)
{
    tStat=xmlhttp2.responseText;        
    document.getElementById("txtHint").innerHTML+=" withintest "+tStat;
    return tStat;
}
Kristoffer Sall-Storgaard
  • 10,576
  • 5
  • 36
  • 46
  • Having readyState commented out was an accident, I was just trying different things to solve the issue: that the function returns the value late. Read my comment on the other answer for more in-depth on this. I just don't know what the proper way to deal with this is. Thanks though. – fvertk Feb 13 '12 at 10:35