title: angularjs directive validation unique email check before send
body: <h2>html</h2>
  
  <pre><code>&lt;input type="email" data-input-feedback="" data-ng-model="user.email" data-unique-email="" required="required" placeholder="Email" class="form-control" id="email" name="email"&gt;
  </code></pre>
  
  <h2>js</h2>
  
  <pre><code>.directive('uniqueEmail',function (User) {
      return {
          require:'ngModel',
          restrict:'A',
          link:function (scope, element, attrs, ngModelCtrl) {
              ngModelCtrl.$parsers.push(function (viewValue) {
                  /*
                   Is there a way to check if it's a valid email ?
                  both ngModelCtrl.$valid and ngModelCtrl.$error.email doesn't work 
                  */
                  User.isUniqueEmail(viewValue).then(function(data){
                      ngModelCtrl.$setValidity('uniqueEmail', !data.email);
                  });
                  return viewValue;
              });
          }
  
      };
  });
  </code></pre>
  
  <p>so is there a way to check if it's a valid email
  before sending the value to the server ?</p>
  
  <h2>UPDATE</h2>
  
  <pre><code>ngModelCtrl.$parsers.push
  </code></pre>
  
  <p>using push() here to run it as the last parser, after we are sure that other validators were run</p>
  
  <p>so only if required and email validation are passed
  do the call to check for unique email</p>
  
  <h2>END UP</h2>
  
  <pre><code>.directive('uniqueEmail',function (User) {
          return {
              require:'ngModel',
              restrict:'A',
              controller:function ($scope) {
                $scope.isValidEmail = function(){
                    return $scope.form.email.$error.email;
                }  
              },
              link:function (scope, element, attrs, ngModelCtrl) {
                  var original;
                  // If the model changes, store this since we assume it is the current value of the user's email
                  // and we don't want to check the server if the user re-enters their original email
                  ngModelCtrl.$formatters.unshift(function(modelValue) {
                      original = modelValue;
                      return modelValue;
                  });
                  // using push() here to run it as the last parser, after we are sure that other validators were run
                  ngModelCtrl.$parsers.push(function (viewValue) {
                      if (viewValue &amp;&amp; viewValue !== original ) {
                          if(scope.isValidEmail(viewValue)){
                              User.isUniqueEmail(viewValue).then(function(data){
                                  ngModelCtrl.$setValidity('uniqueEmail', !data.email); 
                              });
                          }
                          return viewValue;
                      }
                  });
              }
  
          };
      });
  </code></pre>
  
  <h2>With compile and priority</h2>
  
  <pre><code>.directive('uniqueEmail',function (User) {
          return {
              require:'ngModel',
              restrict:'A',
              priority:0,
              compile: function compile(tElement, tAttrs, transclude) {
                  return function (scope, element, attrs, ngModelCtrl) {
                      var original;
                      // If the model changes, store this since we assume it is the current value of the user's email
                      // and we don't want to check the server if the user re-enters their original email
                      ngModelCtrl.$formatters.unshift(function(modelValue) {
                          original = modelValue;
                          ngModelCtrl.$setViewValue(original);
                          return modelValue;
                      });
                      // using push() here to run it as the last parser, after we are sure that other validators were run
                      ngModelCtrl.$parsers.push(function (viewValue) {
                          if (viewValue &amp;&amp; viewValue !== original ) {
                              if(scope.isValidEmail()){
                                  User.isUniqueEmail(viewValue).then(function(data){
                                      ngModelCtrl.$setValidity('uniqueEmail', !data.email); 
                                  });
                              }
                              return viewValue;
                          }
                      });
                      scope.isValidEmail = function(){
                          return scope.form.email.$isvalid;
                      }  
                  }
              }
          }    
      });
  </code></pre>
  
  <p>it still doesnt work the value of scope.form.email.$isvalid
  is unreiable and seems out of date :(</p>