views:

113

answers:

5

I have the following JavaScript (and jQuery) code:

function checkEmail(email) {
    if (email.length) {
        $.getJSON('ajax/validate', {email: email}, function(data){
            if (data == false) {
                // stuff
            }
            return data;
        })
    }
}

I want the anonymous function to return data to the parent function, checkEmail(). I tried doing something like this:

function checkEmail(email) {
    if (email.length) {
        var ret = null;
        $.getJSON('ajax/validate', {email: email}, function(data){
            if (data == false) {
                // stuff
            }
            ret = data;
        })
        return ret;
    }
}

But of course this won't work because the $.getJSON() call is asynchronous, so it will return ret before the GET request is finished.

Any thoughts here?

Thank you!

+6  A: 

Generally, the best way to handle this type of issue is to use some form of callback function. Actually, it is really the only practicable solution -- the only other option is coding your own extensions to the browser, and that is a little much (unless you really like banging your head against a wall). There are actually quite a few parallel questions on these boards: you might try searching for some, many are very good.

Modifying your code:

function checkEmail(email) {
    /*
        original parts of the function here!
    */

    if (email.length) {
        $.getJSON('ajax/validate', {email: email}, function(data){
            if (data == false) {
                // stuff
            }
            checkEmailResponse( data );
        })
    }
}

function checkEmailResponse( data )
{
    // do something with the data.
}
Christopher W. Allen-Poole
A: 

Use continuation passing style

toby
A: 

You could have the parent function block until there is something there. And to reduce the CPU intensiveness, you could use a timeout of somekind.

function checkEmail(email) {
if (email.length) {
    var ret = null;
    $.getJSON('ajax/validate', {email: email}, function(data){
        if (data == false) {
            // stuff
        }
        ret = data;
    }) 
   while(ret == null){

   }
   return ret;
}

}

Hope this helps.

dharga
A: 

You'll just have to change the way you approach the problem. You know that what you have above won't work, so you can't think in terms of "call a function and operate on its return value".

You'll need to switch to something like toby's suggestion of CPS, or depending on what's triggering this function, handling it with custom events.

Peter Bailey
+2  A: 

You should as well use a callback because the call is asynchronous and therefore design you whole JavaScript source around that idea (as the others pointed out).

If you really really need to get it as a return value you need to turn the asynchronous call off but this is not recommended at all, because it blocks the page till the response is there.

function checkEmail(email, callback) {
    if (email.length) 
    return $.ajax({
      data:  {email: email},
      url: 'ajax/validate',
      async: false
     }).responseText; // only the raw response text of the XMLHttpRequest
    }
}
Daff