0

I am using foundation with abide validation and I am trying to make a custom validator to check if an email entry already exists in our database. However, I can't seem to be able to change the value of the valid variable from true to false inside the if else statement. It always returns true, even when the alert "it doesn't work" successfully launches.

$(document).foundation({
  abide: {
    live_validate: false, // validate the form as you go
    validate_on_blur: false,
    patterns: {
      positive_price: /^\+?[0-9]*\,?[1-9]+$/,
    },
    validators: {
      emailVerification: function(el, required, parent) {
        var email = el.value,
          ajax = 1,
          valid = true;

        $.ajax({
          type: "GET",
          url: "/check.do?action=userEmailAvailable",
          data: "userEmail1=" + email + "&ajax=" + ajax,
          success: function(data) {
            if (data.result == 1) {
              alert("it works");
              valid = true;
            } else {
              alert("it doesn't work");
              valid = false;
            }
          }
        });

        return valid;
      }
    }
  }
});
Svedr
  • 589
  • 2
  • 6
  • 21
  • Why don't you do a `console.log(data)` right after you get your data to see what you really get as a result. – xpy Sep 21 '15 at 16:05
  • as @imjared said, you need to work with `$.Deferred` object: https://api.jquery.com/category/deferred-object/ – Marcos Pérez Gude Sep 21 '15 at 16:11
  • You're missing the A from ajax, "asynchronous". You're always going to get a return of `true` because the ajax success handler executes after the `valid` has been returned. – imjared Sep 21 '15 at 16:13

1 Answers1

0

This is happening because ajax call is asynchronous. Take a look here and here to understand better.

Try: First put your ajax call inside a function and return the valid atributte:

function foo(){
    var email = el.value,
    ajax = 1,
    valid = true;

    $.ajax({
          type: "GET",
          url: "/check.do?action=userEmailAvailable",
          data: "userEmail1=" + email + "&ajax=" + ajax,
          success: function(data) {
            if (data.result == 1) {
              return true;
            } else {
              return false;
            }
          }
    });
}

The better approach is to organize your code properly around callbacks. You can make foo accept a callback and use it as success callback. So this

var result = foo();
// code that depends on 'result'

becomes

foo(function(result) {
    // code that depends on 'result'
});

Here we pass a function as argument to foo. You can pass any function reference, for example:

function myCallback(result) {
    // code that depends on 'result'
}
foo(myCallback);

foo itself is defined as follows:

function foo(callback) {
    $.ajax({
        // ...
        success: callback
    });
}

callback will refer to the function we pass to foo when we call it and we simply pass it on to success. I.e. once the AJAX request is successful, $.ajax will call callback and pass the response to the callback (which can be referred to with result, since this is how we defined the callback).

You can also process the response before passing it to the callback:

function foo(callback) {
    $.ajax({
        // ...
        success: function(response) {
            // e.g. filter the response
            callback(filtered_response);
        }
    });
}

It's easier to write code using callbacks than it seems. After all, JavaScript in the browser is heavily event driven (DOM events). Receiving the AJAX response is nothing else but an event. Difficulties could arise when you have to work with third party code, but most problems can be solved by just thinking through the application flow.

Community
  • 1
  • 1
Marcelo Machado
  • 1,179
  • 2
  • 13
  • 33
  • Please don't post link only answers. Those links move or go away and this is no longer helpful. – Sterling Archer Sep 21 '15 at 16:15
  • The links are from stackoverflow and were used to support the learning about the subject, I edited the answer with solution – Marcelo Machado Sep 21 '15 at 21:23
  • Hey I've tried with your solution, however i get the console error data is undefined, could you please check it out. Thank you. https://jsfiddle.net/6m9ff426/ – Svedr Sep 23 '15 at 10:02