Multiple validation directives not working-Collection of common programming errors

I’m trying to write my own set of directives. I have written following two directives:

  • eaValidateEmail (Validates the format of the email address)
  • eaValidateUnique (Will validate the uniqueness by a call to a rest service once complete)

What I want to achieve:

  • First the eaValidateEmail directive is executed which returns false until the format of the email is correct
  • Then and only then the eaValidateUnique directive should execute and check if the email address is taken already over a rest service. If the value is not found it will return true, else it will return false.

What’s happening

When I only add the eaValidateEmail directive, everything is working and the format of the email is validated.

But as soon I add the eaValidateUnique directive then the eaValidateEmail directive is left out and the ctrl.$valid method of the eaValidateUnique directive is always passing even though ctrl.$valid is false in console.log.

I have read through the AngularJS documentation, bought two books but the examples are always very basic. Currently I can’t figure out where the problem could be located. It looks like there is a clash with ngModelController but I can’t figure out the right way to solve this issue.

I’m currently testing with the ValidateCtrlNew form. So the field in the “New” section of the html form.

Questions:

  • Does anybody know how to write the directives so that they are executed in serial order as I add them as attributes to the input element?
  • How can I prevent such clashes with directives? Isolated scope is also no option for multiple directives.

Here is the jsfiddle: http://jsfiddle.net/charms/6j3U8/230/


    
            
            New
            
Invalid: Please enter your email. This is not a valid email. Checking email.... This email is already taken. .directive('eaValidateUnique', ['$http', function($http) { return { restrict: 'A', require: 'ngModel', link: function(scope, elem, attr, ctrl) { ctrl.$parsers.push(function(viewValue) { console.log(ctrl); //ctrl.$setValidity('eaValidateUnique', true); if(ctrl.$valid) { ctrl.$setValidity('eaValidateUnique', false); console.log("valid was true"); } }); } }; }]) .directive('eaValidateEmail', [function() { return { restrict: 'A', require: 'ngModel', link: function(scope, elem, attr, ctrl) { var EMAIL_REGEXP = /^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/; ctrl.$parsers.push(function(viewValue) { // set validity to true to clear out if previous validators fail ctrl.$setValidity('eaValidateEmail', true); if(ctrl.$valid) { // set validity to false as we need to check the value here ctrl.$setValidity('eaValidateEmail', false); if(viewValue !== undefined && viewValue !== "" && EMAIL_REGEXP.test(viewValue)) { // if the format of the email is valid then we set validity to true ctrl.$setValidity('eaValidateEmail', true); ctrl.$setValidity('eaValidateEmailCheck', true); console.log("TRUE"); } else { // if the format of the email is invalid we set validity to false ctrl.$setValidity('eaValidateEmail', false); ctrl.$setValidity('eaValidateEmailCheck', true); console.log("FALSE"); } } return viewValue; }); } }; }]);