0

There are about a million posts on SO about async callbacks, but I cannot figure out how to get mine to work

I have an AJAX request:

function checkName();
    var ajax = new XMLHttpRequest();
    ajax.open("POST", "index.php", true); // true = async
    ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

    ajax.onreadystatechange = function(){
        if(ajax.readyState == 4 && ajax.status == 200){
            var pass = ajax.responseText + 0;
        }
    }

    ajax.send("emailcheck="+email);

return pass;
}

The only possible outcomes for pass are 1 or 0.

I've tried moving the return immediately after the assignment of pass, but still nothing. That's when I started looking around on here and found callbacks, but I'm having trouble figuring out how to do it.

What I would like to do is have something like:

if(checkName()){
    // Do stuff
}else{}

I don't want to do a synchronous ajax request (i.e. false for third param), because that stops an animation I have and also prevents the user from performing other tasks on the site for the short time the call takes place.

I know this is very similar to other posts about the topic, I just can't quite figure it out.

Thank you in advance.

Birrel
  • 4,754
  • 6
  • 38
  • 74
  • possible duplicate of [How to return the response from an Ajax call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – Andreas Jan 08 '15 at 20:44
  • I looked at that but couldn't figure out where I was going wrong. – Birrel Jan 08 '15 at 20:54
  • 1
    Lose the content type. It's ignored by Chrome as unsafe. – Mouser Jan 08 '15 at 21:45
  • @Mouser do you mean taking out the entire line `ajax.setRequestHeader...`? I tried that, but then it doesn't work properly anymore. Unavailable names are said to be available. – Birrel Jan 08 '15 at 22:11
  • The browser should detect the correct request header by itself. x-www-form-urlencoded vs. multipart. – Mouser Jan 08 '15 at 22:13

1 Answers1

2

Only with a synchronous call you can implement this. And no one would want that. You said it yourself.

if(checkName()){ 
     // Do stuff
}else{}

You need to use a callback function indeed. See this example:

function checkName(callBack) {
    var ajax = new XMLHttpRequest();
    ajax.open("POST", "index.php", true); // true = async

    if (callBack)
    {
       ajax.callBack = callBack;
    }
    ajax.onreadystatechange = function(){
        if(this.readyState == 4 && this.status == 200){
            if (this.callBack)
            {
                this.callBack(this.responseText);
            }
        }
    }

    ajax.send("emailcheck="+email);

}

function checkNameFinish(data)
{
    alert(data);
}

checkName(checkNameFinish);

checkName now accepts an argument callBack. This has to be a function. When the readystate completes it checks if there's a callBack set. If so then execute the callBack function and pass the response as argument.

Mouser
  • 13,132
  • 3
  • 28
  • 54
  • I tried this, and I do get the alert, but how can I use it in the way I'm looking for? I mean, how can I use the `responsetext` in the `if(checkName()){...}`. Or is such a thing just not possible? – Birrel Jan 08 '15 at 22:08
  • 1
    Not possible for asynchronous calls at this moment for all browsers. You can look into promises https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise. But they aren't supported widely and still experimental. – Mouser Jan 08 '15 at 22:10
  • Ok, thank you! One more thing: in my function I have something like `$('.output').html('...')` immediately before `var ajax = new XMLHttpRequest` but the inner html of `.output` only changes for the asynchronous version, but NOT the synchronous version. I would have though that it would be changed on account of it coming before the ajax stuff, but it doesn't. – Birrel Jan 08 '15 at 22:15
  • @Birrel It should work just fine. Maybe there's an error in it? jquery should execute before the ajax call. – Mouser Jan 08 '15 at 22:18
  • the reason was that the jquery instruction came immediately before the ajax call - so close that the ajax call initiated before the jquery instruction could be completely finished, thus no change. I added a 20ms delay, which isn't even perceptible, and that gives it plenty of time to complete before the ajax call is made. – Birrel Jan 09 '15 at 07:27