Is it possible to have more than one custom validator per Angular field?

I tried this code:

   .directive('uniqueUsername', function (isUsernameAvailable) {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: function (scope, element, attrs, ngModel) {
                ngModel.$asyncValidators.uniqueName = isUsernameAvailable;
            }
        };
    })
    .directive("isMinSix", function () {
        return {
            restrict: "A",
            require: "ngModel",
            link: function (scope, element, attributes, ngModel) {
                ngModel.$validators.isMinSix = function (modelValue) {
                    if (modelValue != null && modelValue.length < 6) {
                        return true;
                    } else {
                        return false;
                    }
                }
            }
        }
    })
    .factory('isUsernameAvailable', function (appConstant, $q, $http) {
        return function (username) {
            var deferred = $q.defer();
            var url = appConstant.baseUrl + '/api/user/existsByName';
            $http({
                url: url,
                method: "PUT",
                data: {
                    userName: username
                }
            }).then(function () {
                    // Found the user, therefore not unique.
                    deferred.reject("User name is taken");
                }, function () {
                    // User not found, therefore unique!
                    deferred.resolve();
                });
            return deferred.promise;
        }
    })

      

My problem is that when I add these two directives to the input only and then put the debug point in the checks, only one or the other will fire. I cannot get them both to work correctly at the same time:

                <input class="inputField"
                       id="registerUserName"
                       name="registerUserName"
                       is-min-six
                       ng-model="aus.registerUserName"
                       ng-model-options="{ debounce: 3000 }"
                       ng-required="true"
                       placeholder="Username"
                       type="text"
                       unique-username
                       value="" />

      

Does anyone have any idea what I might be doing wrong?

+3


source to share


2 answers


It is possible to have multiple validators, but asynchronous validators will only execute if synchronous validators passed. This can be found in the documentation and source code :

Also, all asynchronous validators will only run after all synchronous validators have passed.



This makes sense as asynchronous validators are likely to be remote procedures that would be wasteful if the field is invalid anyway. It is of course possible to modify the source code linked above to make it work in its own way, which seems to always run asynchronous validators.

+2


source


According to this nice resource http://www.yearofmoo.com/2014/09/taming-forms-in-angularjs-1-3.html

asynchronous validations will fail if all previous normal validators (validators present inside ngModel. $ validators) have passed. This narrowing allows the developer (yes, you) to prevent the validator from making excessive callbacks when the username input is invalid.



Also I am confused by the directive name isMinSix, which returns valid if modelValue.length <6. Angular has built-in minlength and maxlength directives.

+1


source







All Articles