0

I am trying to create an email exists validation directive which makes an ajax call to see if email exists.I am unable to have the validation updated for the field with this code.

app.directive('uniqueValidator', ['UniqueValidatorService',function(uniqueValidatorService) 
    {
        var linkFn=function(scope, elem, attrs,ngModel)
        {
            var vm=this;
            vm.ngModel=ngModel;
            vm.scope=scope;
            var config=scope.$eval(attrs.uniqueValidator);
            console.log('Value of the atribute'+window.angular.toJson(config));
            /*If the value is truly unique then we would want to set validation as passed*/
            vm.successCallback=function successCallback(unique){
                vm.ngModel.$setValidity('unique',false);
                console.log('Value of validity success case'+vm.ngModel.$valid);
            };
            /*Set validity as false to make sure we have a */
            vm.errorCallback=function errorCallback(error){
                 ngModel.$setValidity('unique',true);
                 console.log('Value of validity'+ngModel.$valid);
            };
            var blurHandler=function(event){
                console.log('In blur'+ngModel);
                 if (!ngModel || !elem.val()) return;
                var currentValue=elem.val();
                uniqueValidatorService.checkUniqueness(config.url,config.property,currentValue).then(function(data){
                    vm.successCallback(data);

                },function(error){vm.errorCallback(error)});
            }
            elem.bind('blur',blurHandler.bind(vm));

        };
        return {
            restrict: 'A',
            scope:{},
            require:'ngModel',
            link: linkFn
        };
    }
    ])
    .directive('uniqueErrorMessage',function(){
        var linkFn= function(scope, elem, attrs,ngModel){
            scope.message='Email is in use';
            console.dir(scope.registrationForm.email.$error);
        };
         return {
            restrict: 'E',
            replace:true,
            template:'<span ng-show="registrationForm.email.$dirty && registrationForm.email.$error.unique" >{{message}}</span>',
            link: linkFn
        };

        });

The unique error message directive is not getting updated properly as per the validation outcome.Even if the validation passes,it still shows on DOM. Also I am seeing that ngModel.$valid for the input element is coming as true even if the validation is failed.I have tried encapsulating the $setValidity inside a scope.$apply but that causes a digest in progress error.Any help in this regard is appreciated.I will not be able to include ui router validation or upgrade my angularjs version to use the newer validation framework

Thanks, Rahul

1 Answer 1

3

Here is an example that may help:

var app = angular.module('app', []);
app.controller('ctrl', function() {});

app.directive('unique', function(userFactory) {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attr, ngModelController) {
      element.on('blur', function() {
        if (ngModelController.$viewValue != '') {
          userFactory.tryUsername(ngModelController.$viewValue)
            .then(
              function succcess(result) {
                ngModelController.$setValidity('unique', true);
              },
              function fail(result) {
                ngModelController.$setValidity('unique', false);
              }
            );
        }
      });
    }
  }
});

app.factory('userFactory', function($q) {
  return {
    tryUsername: function(username) {

      var deferred = $q.defer();
      if (username == 'john')
        deferred.reject('john already exists!');
      else if (username == 'tim')
        deferred.resolve('tim');
      else if (username == 'hank')
        deferred.reject('hank already exists!');
      else
        deferred.resolve(username);

      return deferred.promise;
    }
  }

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="app" ng-controller="ctrl">
  <form name="form">
    Enter a Username (john and hank are taken):
    <br />
    <input type="text" ng-model="username" name="username" unique /> <span ng-show="form.username.$error.unique">Username is taken!</span><br />
    {{ form.username.$error }}
  </form>
</body>

Sign up to request clarification or add additional context in comments.

1 Comment

THank you for your response ,actually it was an issue with me not properly parsing the http response in the service function.THanks for your help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.