views:

95

answers:

3

Hi,

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  A: 

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;
            }
        });
    }            
}
David Hedlund
Thank you! thank you! thank you!! That worked great! :)
Mantisimo
+2  A: 

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'.

Felix Kling
Thanks, that works great cheers, Yeah I was getting desperate at that stage so I used the eval. I thought that was the case.
Mantisimo
A: 

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;             
    } 
Marimuthu Madasamy
I did try and it didnt work
Mantisimo
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.
Marimuthu Madasamy
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.
Marimuthu Madasamy
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.
Mantisimo
This is working. Try this in jsfiddle: http://jsfiddle.net/VqT6n/
Marimuthu Madasamy