4

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 an input only and then put a 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 ideas what I may be doing wrong?

Samantha J T Star
  • 30,952
  • 84
  • 245
  • 427
  • 1
    http://stackoverflow.com/questions/19177732/what-is-the-difference-between-ng-if-and-ng-show-ng-hide – Himmet Avsar Jan 07 '15 at 13:24
  • Take a look at how angular handles validation, you seem to be rolling your own partially, but you should be able to use it directly in the dom. – Mathew Berg Jan 07 '15 at 14:57
  • The problem is I wanted to get a message into the title of the icon and with Angular validation I am not sure how to do that. Hopefully someone can come up with an example. –  Jan 07 '15 at 16:52
  • 1
    Can you create a plunker for this? – DeborahK Jan 09 '15 at 19:42
  • Is **require: "ngModel",** needed for the directives? – camden_kid Jan 09 '15 at 19:45
  • 1
    Are you sure that 'modelValue.length < 6' is correct? (may be 'modelValue.length > 6' is right condition) – Ilya Jan 10 '15 at 10:18

2 Answers2

3

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

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

This makes sense because asynchronous validators will most likely be remote procedures which would be wasteful if the field is invalidated anyway. Of course, it's possible to modify the source code linked above to make it work your preferred way, which appears to be to always run the asynchronous validators.

Steve Klösters
  • 9,427
  • 2
  • 42
  • 53
1

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

asynchronous validations will NOT run unless all of the prior normal validators (the validators present inside of ngModel.$validators) have passed. This constriction allows for the developer (yes you) to prevent the validator from making excessive backend calls when the username input data is invalid.

Also I'm confused about directive name isMinSix that returns valid if modelValue.length < 6. There are built-in directives minlength and maxlength in Angular.