2

I have used jquery validation to validate email. But the variable whose value is changed in success function is not accessible outside it. It can be done with async=false, but that destroys the purpose of Ajax.

Below is the code:

$.validator.addMethod('verifyemail',function(value,element){        
    $.ajax({
        type: "POST",
        url : $.app.urls('base_url')+'account/check_email',
        data: {'email' : value},
        success: function(msg){
            //If email exists, set response to true
            if( msg.status == 'false' )
                respond = false;
            else
                respond = true;
        }
    })
    console.log(respond);
    return respond;
}, "Email is Already Taken");
1
  • Problem: Trying to use undefined variable. Explanation: AJAX request will take some time, you can't read results right after $.ajax call. Solution: Event driven program flow, separate validator methods and AJAX requests. Check for valid and default to invalid. Commented Sep 28, 2013 at 19:25

4 Answers 4

4

You can't set the value in an asynchronous function like that. The way in which this works is that respond would be set to a value. Then your asynchronous ajax call would fire off, as soon as it fires off the rest of the code below your ajax call would execute. Once the ajax call returns, the code in the success callback will be executed. Most likely, by this time your validator function would have finished executing.

Since you're using this ajax call in a validator, you would want to run this in series since the validation depends on the result of your ajax call. You could accomplish this by setting async: false.

Here is a useful resource on asynchronous callbacks and how they work:

http://blog.parse.com/2013/01/29/whats-so-great-about-javascript-promises/

And another covering jQuery's AJAX function async vs sync:

http://net.tutsplus.com/tutorials/javascript-ajax/event-based-programming-what-async-has-over-sync/

Sign up to request clarification or add additional context in comments.

5 Comments

I know about aync:false, but wouldn't that ruin the use of Ajax?
It would only defeat the purpose of running the function asynchronously, but since you need the result of the http request to determine the validation, you need to run it in series.
Welcome for a detail overview of everything required
The async:false stops all other validation, what to do?
Could you post more of a code sample on something like jsfiddle.net? I can probably help you more if I can see the validators
1

Ajax call is asynchronous, meaning when you call console.log(respond); The variable respond is still not available. If you need to access it outside the success function, you can trigger a custom event and get respond in the event handler.

And of course, you have to put respond in outer scope.

5 Comments

Example if possible please
I think jquery.validator is mostly for client side validation. Since form validations are done both on client and server side, I suggest you post(ajax) the form and show the returned error if any. Using ajax in sync mode locks the browser, giving bad user experience.
That's the problem I am facing just now
If you don't use jquery.validator there is no problem. That's what I am saying.
But that's the main requirement
0

respond is already a global variable (lack of var keyword), but the asynchronous nature of AJAX means that it won't necessarily be available when the following lines run, so you need to sequence it in one of a few ways

  • Make it synchronous (but the question rules that out)
  • put the responding code inside of the same anonymous function
  • You could also make a while loop that spins until respond is set, but that would probably be a poor solution.

Hope that helped

Comments

-1

to access the respond variable you need to either define it in upper scope

$.validator.addMethod('verifyemail',function(value,element){        
    var respond = true; // scope of variable to current function
    $.ajax({
        type: "POST",
        url : $.app.urls('base_url')+'account/check_email',
        async: false,  
        data: {'email' : value},
        success: function(msg){
            //If email exists, set response to true
            if( msg.status == 'false' )
                respond = false;
            else
                respond = true;
        }
    })
    console.log(respond);
    return respond;
}, "Email is Already Taken");

3 Comments

ok got it, there is issue with async nature, please check updated answer
@jrthib had already given the answered before you pointed out the aync nature. So I have ticked there.
-1 for switching to synchronous mode instead of trying to solve main problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.