validation - AngularJS - Why asynchronous validators are not called when other validators fail? -


is not don't or anything, problem synchronous validators behave differently. called, if other validator failed before. so, there uneven behaviour in validators, can cause problems.

i tested simple program.

i created synchronous validator , asynchronous validator validate same. in both validators submit error in "typical" way with:

ctrl.$validators.sync= function(modelvalue,viewvalue){... 

and submit additional error(for example tell there connection problem in asynchronous validation) with:

ctrl.$setvalidity('syncplus',... 

also, beside uneven behaviour, additional validation error causes , additional problem in asynchronous validators:

as have seen, async "typical" validation reset immediatelly if input modified. (i don't know where) additional validator never reset. and, async validator not called when other validator fails, can't update additional validator, error before still shown, though can valid input.

please, try program in plunker:

here can see js code whith validators:

angular.module('app',[]) .directive('async', function($q,$timeout){     return{         restrict: 'a',         require: 'ngmodel',         link: function(scope, elm, attrs, ctrl){              var nono_username= ['a','aa','aaa','aaaaa']; // should fail 1 5 a's, not 4 a's              ctrl.$asyncvalidators.async= function(modelvalue,viewvalue){                  scope.data.called+= 'a'; // way know async has been called                 var def= $q.defer();                  $timeout(function() { // mock delayed response                     if(nono_username.indexof(modelvalue)===-1){ // username available                         ctrl.$setvalidity('asyncplus',true);                         def.resolve();                     } else {                         ctrl.$setvalidity('asyncplus',false);                         def.reject();                     }                 }, 200);                  return def.promise;             };         }     }; }) .directive('sync', function($q){     return{         restrict: 'a',         require: 'ngmodel',         link: function(scope, elm, attrs, ctrl){              var nono_username= ['a','aa','aaa','aaaaa']; // should fail 1 5 a's, not 4 a's              ctrl.$validators.sync= function(modelvalue,viewvalue){                 scope.data.called+= 's'; // way know sync has been called                 ctrl.$setvalidity('syncplus',nono_username.indexof(modelvalue)===-1);                 return nono_username.indexof(modelvalue)===-1;             };         }     }; }) /* maybe solution resetting asyncplus? .directive('asyncplus', function($q){     return{         restrict: 'a',         require: 'ngmodel',         link: function(scope, elm, attrs, ctrl){             ctrl.$validators.asyncplus= function(modelvalue,viewvalue){                 return true;             };         }     }; }) */ .controller('controller',['$scope',function($scope){     $scope.data= {username:'',called:''}; }]); 

conclusion:

  • why asynchronous validators not called when other validators fail?
  • why additional $setvalidity validators not reset?
  • can reset validators in simple way? (i found creating synchronous validator same name , include directive in input solves it, put in commented code above)
  • what think best option avoid problems or wich workaround should use?

this question want see answered well. resetting validators, did try $setpristine on form? helped me out in cases needed reset 1 particular field, can on form

https://docs.angularjs.org/api/ng/type/form.formcontroller#$setpristine https://docs.angularjs.org/api/ng/type/ngmodel.ngmodelcontroller#$setpristine


Comments