3

Can any give me a clue why this isn't working? The function returns undefined. It alerts a boolean values but still return undefined?!

Thanks

    function IsUniqueEmail() {

        var email = $("#<%=EmailAddress.ClientID%>").val();

        if (email.length > 0) {

            $.ajax({
                url: 'handlers/validator.ashx',
                dataType: 'json',
                data: { "n": "email", "v": email },
                async: false,
                success: function(data) {
                    alert(eval(data.success));
                    return eval(data.success);
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    console.log(textStatus, errorThrown);
                    return true;
                }
            });
        }            
    }

    $(document).ready(function() {

        var execScript = $(".buttonStep1").attr("href").replace("javascript:", "");

        $(".buttonStep1").attr("href", "#").click(function() {
            // Add before click logic here
            var IsOk = IsUniqueEmail();
            if (IsOk) {
                $("#EmailAddressInUseMessage").hide();
                eval(execScript);
            }
            else {
                $("#EmailAddressInUseMessage").show();
            }
        });
    });

this is the response of the ajax call

    { "success": false, "error" : "ERROR_EMAILINUSE" }
2
  • eval is not a good practice... Commented Aug 4, 2010 at 13:28
  • Agreed, I was getting desperate when I tried the eval statement :) Commented Aug 6, 2010 at 8:22

3 Answers 3

7

The script execution path when using AJAX is not linear. Your IsUniqueEmail will exit before the AJAX request has received a response, returning nothing.

What you're returning is being sent to $.ajax, which is the method that is invoking success, and there it is probably being disregarded.

You could rewrite your code in this manner:

$(document).ready(function() {
    $(".buttonStep1").click(function() {

        IsUniqueEmail();

        // never follow this link
        return false;

    });
});

In this way, the button click just starts the request - it doesn't go ahead and do anything else. After that, you do all your magic in the AJAX response:

function IsUniqueEmail() {

    var email = $("#<%=EmailAddress.ClientID%>").val();

    if (email.length > 0) {

        $.ajax({
            url: 'handlers/validator.ashx',
            dataType: 'json',
            data: { "n": "email", "v": email },
            async: false,
            success: function(data) {
                alert(eval(data.success));

                if(eval(data.success)) {

                   // Execute code to continue after the click here

                }
            },
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                console.log(textStatus, errorThrown);
                return true;
            }
        });
    }            
}
Sign up to request clarification or add additional context in comments.

Comments

2

You cannot do it that way. IsUniqueEmail(); will be return before the Ajax call finished. It is asynchronous! You have to put the logic into your callback function:

function IsUniqueEmail() {

    var email = $("#<%=EmailAddress.ClientID%>").val();

    if (email.length > 0) {

        $.ajax({
            url: 'handlers/validator.ashx',
            dataType: 'json',
            data: { "n": "email", "v": email },
            async: false,
            success: function(data) {
               if (data.success) {
                   $("#EmailAddressInUseMessage").hide();
                   eval(execScript);
               }
               else {
                   $("#EmailAddressInUseMessage").show();
               }
            },
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                console.log(textStatus, errorThrown);
            }
        });
    }            
}

If you specify the data type as JSON, you don't have to use eval to parse it. data will already be an object. And even if data.success contains a string, compare it to a string instead of using eval: data.success == 'true'.

1 Comment

Thanks, that works great cheers, Yeah I was getting desperate at that stage so I used the eval. I thought that was the case.
1

Adding to other answers, what you can do is you need to store the result of ajax call in a variable which has the scope of your IsUniqueEmail function. Your Ajax success call back can access the variable and update it (with the help of closure). After the Ajax call completes, you can return the updated variable (since it is not async).

function IsUniqueEmail() { 

        var email = $("#<%=EmailAddress.ClientID%>").val(); 
        var isUnique = false;

        if (email.length > 0) { 

            $.ajax({ 
                url: 'handlers/validator.ashx', 
                dataType: 'json', 
                data: { "n": "email", "v": email }, 
                async: false, 
                success: function(data) { 
                    alert(eval(data.success)); 
                    isUnique = eval(data.success); 
                }, 
                error: function(XMLHttpRequest, textStatus, errorThrown) { 
                    console.log(textStatus, errorThrown); 
                    return true; 
                } 
            }); 
        }
        return isUnique;             
    } 

3 Comments

wonder how it didn't work. I have used this pattern for similar kind of validation and it is working. Moreover this is perfectly valid in the context of closure.
Further if you do not embed your other codes inside this method, the method would just do a 'single unit of work' which can be reused as an utility wherever you want to validate your emails.
The ajax code seems to executes independantly of the function. I stepped through it in firebug. It runs through. It alerts the data.success value but it doesn't set the isUnique flag. I was tearing my hair out trying to understand why because I agree this make perfect sense.

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.