AngularJS: integrating with server-side validation

This is another case where a custom directive is your friend. You’ll want to create a directive and inject $http or $resource into it to make a call back to the server while you’re validating.

Some pseudo code for the custom directive:

app.directive('uniqueEmail', function($http) {
  var toId;
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, elem, attr, ctrl) { 
      //when the scope changes, check the email.
      scope.$watch(attr.ngModel, function(value) {
        // if there was a previous attempt, stop it.
        if(toId) clearTimeout(toId);

        // start a new attempt with a delay to keep it from
        // getting too "chatty".
        toId = setTimeout(function(){
          // call to some API that returns { isValid: true } or { isValid: false }
          $http.get('/Is/My/EmailValid?email=" + value).success(function(data) {

              //set the validity of the field
              ctrl.$setValidity("uniqueEmail', data.isValid);
          });
        }, 200);
      })
    }
  }
});

And here’s how you’d use it in the mark up:

<input type="email" ng-model="userEmail" name="userEmail" required unique-email/>
<span ng-show="myFormName.userEmail.$error.uniqueEmail">Email is not unique.</span>

EDIT: a small explanation of what’s happening above.

  1. When you update the value in the input, it updates the $scope.userEmail
  2. The directive has a $watch on $scope.userEmail it set up in it’s linking function.
    • When the $watch is triggered it makes a call to the server via $http ajax call, passing the email
    • The server would check the email address and return a simple response like ‘{ isValid: true }
    • that response is used to $setValidity of the control.
  3. There is a in the markup with ng-show set to only show when the uniqueEmail validity state is false.

… to the user that means:

  1. Type the email.
  2. slight pause.
  3. “Email is not unique” message displays “real time” if the email isn’t unique.

EDIT2: This is also allow you to use form.$invalid to disable your submit button.

Leave a Comment