0

I have an error checking function that is just running me in circles.

function emailValUReq(v, noRet) {
    var textReg = /[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?/;
    if (!v.val()) {
        if (noRet == null) {
            v.nextAll('.errText').html('<br>! Required Field');
        }
        return 1;
    } else if (!textReg.test(v.val())) {
        if (noRet == null) {
            v.nextAll('.errText').html('<br>! Invalid Entry');
        }
        return 1;
    } else {
        $data = new Object;
        $data['email'] = v.val();
        $data['id'] = v.data('cur');
        $.ajax({
            type: "POST",
            url: "/modules/data/dup_check.php",
            data: $data,
            success: function (r) {
                if (r == 'ok') {
                    v.nextAll('.errText').empty();
                    return 0;
                } else {
                    if (noRet == null) {
                        v.nextAll('.errText').html('<br>! An account already exists for this email');
                    }
                    return 1;
                }
            }
        });
    }
}

This function works perfectly overall. It returns 1 on an error, 0 when a value is correctly formatted and unique. The problem comes in when I try to 'add up' the errors from multiple functions.

(area and noRet are passed in)

var vErr=0;
    area.find('.emailvalureq:visible').each(function () {
        vErr += emailValUReq($(this), noRet);
    });

When the input field is empty, or when it is incorrectly formatted, this works properly. As soon as the $.ajax call is fired within the validation script, it seems that the delay messes everything up and vErr ends up being a NaN value.

I have tried doing this as follows, with the same result:

var vErr=0;
area.find('.emailvalureq:visible').each(function () {
    var ve1 = emailValUReq($(this), noRet);setTimeout(function(){vErr+=ve1;},1000);
});

I'm going to be at a family wedding for a couple hours, so I won't be able to respond to any questions / suggestions until later tonight - but any help is appreciated!

A Paul
  • 8,113
  • 3
  • 31
  • 61
Alan
  • 389
  • 1
  • 7
  • 16
  • 1
    Welcome to the wonderful world of **async**! You can't do that. – SLaks Dec 31 '13 at 23:29
  • 1
    Unless you use promises.. – josephtikva1 Dec 31 '13 at 23:32
  • 2
    You could pass a callback argument to your `emailValUReq()` to control the side effect of the asynchronous calls. – Ja͢ck Dec 31 '13 at 23:36
  • possible duplicate of [How to return the response from an AJAX call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – Arun P Johny Jan 01 '14 at 00:32
  • Thanks everyone for the suggestions. I tried using a when / done statement, but I wasn't sure how to get the value returned by the function. What I ended up doing was updating the value of the variable in the function, which works for my purposes! – Alan Jan 01 '14 at 05:17

1 Answers1

0

I tried using a when / done statement as follows:

$.when(emailValUReq($(this),noRet)).done(function(r){vErr+=r;});

but the problem with this was that 'r' was undefined (I was hoping it would pull the returned value from the emailValUReq function).

For me, the solution was to rework the emailValUReq function to simply update the error variable directly, as follows:

function emailValUReq(v, noRet) {
    var textReg = /[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?/;
    if (!v.val()) {
        if (noRet == null) {
            v.nextAll('.errText').html('<br>! Required Field');
        }
        $err++;
    } else if (!textReg.test(v.val())) {
        if (noRet == null) {
            v.nextAll('.errText').html('<br>! Invalid Entry');
        }
        $err++;
    } else {
        $data = new Object;
        $data['email'] = v.val();
        $data['id'] = v.data('cur');
        $.ajax({
            type: "POST",
            url: "/modules/data/dup_check.php",
            data: $data,
            success: function (r) {
                if (r == 'ok') {
                    v.nextAll('.errText').empty();
                } else {
                    if (noRet == null) {
                        v.nextAll('.errText').html('<br>! An account already exists for this email');
                    }
                    $err++;
                }
            }
        });
    }
}

$err=0;
area.find('.emailvalureq:visible').each(function () {
    emailValUReq($(this), noRet);
});

All that I need to then do is delay checking the value of $err for roughly 1 second, which gives the ajax call enough time to run and return the response.

setTimeout(function(){return $err;},1128);

I'm not sure if this was the best response, or the most elegant, but it worked!

Alan
  • 389
  • 1
  • 7
  • 16