views:

679

answers:

3

I'm using xVal with MVC and jquery validate. It all works nicely, until i get to my custom validator that does an ajax call.

the ajax call returns the right value, according to the firbug Net Tab. But something is going wrong and I can't figure it out.

Here's the javascript code:

    function CheckEmail() {
    var res;
    $.ajax({
        type: "GET",
        url: "/User/CheckEmail",
        data: "email=" + $('#EmailAddress').val(),
        success: function(result) {
            res = result;
        }
    });
    if (res == "True") {
        return true;
    }
    else {
        return false;
    }

}

when i step through with firebug, res is showing as undefined. i think that's the problem.

i've spent like 4 hours re-arranging and changing this code and nothing seems to make it work properly.

I have a theory that it's not waiting until the ajax is done to run the if statement. Can anyone confirm or deny that?

+2  A: 

The 'A' in Ajax stands for Asynchronous.

What's happening is, your code is getting called like this:

$.ajax(...);
if (res == "True") {        
   return true;    
} else {        
   return false;    
}

Then later (as in, milliseconds later) the ajax request comes back and calls:

function(result) {
   res = result;        
}

Some would suggest making the Ajax call asynchronous, but this will prevent anything else from happening in the browser until the request comes back, which can be bad for many reasons.

The best solution would be to put your validation logic in the callback, and not in the function that creates and sends the Ajax request.

Example:

function CheckEmail() {    
    $.ajax({        
     type: "GET",        
     url: "/User/CheckEmail",        
     data: "email=" + $('#EmailAddress').val(),        
     success: function(result) {            
      if (result == "True") {
       doSomethingPositive();
      } else {
       warnUserInvalidEmail();
      }
     }    
    });    
}
this would work great if it wasn't being used by xVal but it needs to return true/false for xVal
Patricia
+2  A: 

Yes, you are correct. $.ajax() is an asynchronous call by default. You can add async : false to make it synchronous.

$.ajax({
    type: "GET",
    async: false,
    url: "/User/CheckEmail",
    data: "email=" + $('#EmailAddress').val(),
    success: function(result) {
        res = result;
    }
});
jrummell
i think this might actually be the way to go. b/c i need to return true or false from this function for xVal to use it. and zulrang's solution can't allow for that.
Patricia
+1  A: 

There's no need for a synchronous call to your web server. You should avoid those as much as possible, because the user's browser will be locked up during while it's waiting for the reply.

I've recently written a blog article about remote client-side validation (exactly what you are trying to achieve) showing how to do this with an asynchronous request.

Adrian Grigore
Thanks for the linK! this looks like a much better solution then having the browser wait. much more user friendly. I'm going to try implementing it right now!
Patricia