$asyncValidators run multiple times per element on load (given ng-repeat || ng-(min/max)length)) #14691
Description
Note: for support questions, please use one of these channels: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#question. This repository's issues are reserved for feature requests and bug reports.
Do you want to request a feature or report a bug?
Bug
What is the current behavior?
If you have a model defined already and it's put into an input text element with a custom validator defined and this input field is in an ng-repeat, then, on the page load, the $ayncValidator will be run once, and then run in quick succession run again for every validator directive such as "minlength, maxlength, ng-maxlength, ng-minlength, required".
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar (template: http://plnkr.co/edit/tpl:yBpEi4).
- define a model in the controller
- define a custom directive that has an $asyncValidator linked (put in a console.log before returning the promise)
- create a div with ng-repeat (if this step is omitted, then the problem is only exhibited with ng-maxlength and ng-minlength)
- Inside of the ng-repeat clause create an input type="text" element, and load it up with maxlength, minlength, and required
- take note of how many times the console.log() that was set up in $asyncValidator is tripped when you hit "Run".
- when you go and interact with the element, then it behaves normally and as expected.
http://jsfiddle.net/yofk7u0L/5/
What is the expected behavior?
$asyncValidators only fire once upon directive initialization with a non-empty model, regardless of how many other attribute directives that are validators exist in the element, also regardless of whether they're in ng-repeat or not.
What is the motivation / use case for changing the behavior?
In the application I'm currently working on, a user can have up to 10 of these $asyncValidator input fields loaded up at the same time. With minlength, maxlength, and required enabled on each, this makes 30 EXTRA requests to my API, on top of the 10 that were welcome. If I use ng-minlength and ng-maxlength, it could bump it up an extra twenty (two per input element)
Which versions of Angular, and which browser / OS are affected by this issue? Did this work in previous versions of Angular? Please also test with the latest stable and snapshot (https://code.angularjs.org/snapshot/) versions.
Firefox and Chrome on Angular 1.5.3, 1.5.5, 1.5.6 and v1.5.7-build.4838+sha.cfc8b41 exhibit this behavior.
I'm seeing this happen on both Windows 7 (1.5.3 & 1.5.5) and Linux Fedora 23 KDE (All the above)
Other information (e.g. stacktraces, related issues, suggestions how to fix)
Not sure how to fix this, but I guess:
- Order directives are placed have no bearing
- Synchronous $validators within the same directive as the $asyncValidators behave normally.
- The entire list of $asyncValidators seems to be looped through each time
- I have not tried adding custom directives to the input element, but I suspect that they might behave similarly and contribute to the amount of times
- If you use a combination of ng-repeat and ng-minlength and ng-maxlength that seems to maximize the total number of requests.
- Have not tested to see if other input types are affected