angularjs - Custom directive validator calling REST API too slow to set form.$invalid to prevent form submission -


i have custom directive on input text field calls rest web service api using $http (restful resource actually). web service call typically takes 500ms time call returns, user may have hit on submit button of form , proceed.

how can prevent that?

input field:

<input type="text" data-my-user-input-validation="true" data-ng-model-options="{ updateon: 'blur' }"> 

form:

<form name="myform" role="form" data-ng-submit="myform.$valid && submit()" novalidate> 

custom directive:

app.directive('myuserinputvalidation', function(userinputrestrictionvalidationpost) {     return {         require: 'ngmodel',         link: function(scope, element, attrs, ngmodel) {             var validate = attrs.myuserinputvalidation;              if (validate === 'false') {                 // false, don't need                 return;             }              function setasinvalid(bool) {                 ngmodel.$setvalidity('userinputvalidation', bool);             }              ngmodel.$parsers.push(function(value) {                 if (!value || value.length == 0) return;                  userinputrestrictionvalidationpost.get({                     value: value                 }, function(data) {                     if (data.status === 'ok') {                         // api return ok                         setasinvalid(true);                      } else {                         // failure or error                         setasinvalid(false);                     }                 });                  return value;             })         }     } }); 

answer:

app.directive('myuserinputvalidation', function(userinputrestrictionvalidationpost) {   return {     require : 'ngmodel',     link : function(scope, element, attrs, ngmodel) {         var validate = attrs.myuserinputvalidation;          if(validate === 'false'){             // false, don't need             return;         }          function setasinvalid(bool) {             ngmodel.$setvalidity('userinputvalidation', bool);          }          ngmodel.$asyncvalidators[attrs.name] = function(modelvalue, viewvalue) {             var value = modelvalue || viewvalue;              if(!value || value.length == 0){                 setasinvalid(true);                 return false;             }              return userinputrestrictionvalidationpost.get({ value: value }).$promise.then(function (data) {                 if(data.status === 'ok'){                     // api ok                     setasinvalid(true);                     return false;                  }else{                     // failure or error                     setasinvalid(false);                     return true;                 }             });         };     }   } }); 

for purpose asynchronous validators exists - see $asyncvalidators property in ngmodelcontroller (https://docs.angularjs.org/api/ng/type/ngmodel.ngmodelcontroller)

ngmodel.$asyncvalidators. userinputvalidation = function(modelvalue, viewvalue) {     if (!value || value.length == 0) {       return;     }       return userinputrestrictionvalidationpost.getresultaspromise(value); 

beware of return value. have return promise here.


Comments