Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 3b662fe

Browse files
author
Gonzalo Ruiz de Villa
committed
fix(input): $asyncValidators should allow $parsers
After resolving an async validator, it should compare current viewValue against the value it had when the validator was started before reducing pendingCount. Before this commit the comparison was made between the modelValue when the validation started and the current viewValue.
1 parent 203ea10 commit 3b662fe

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

src/ng/directive/input.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -1709,7 +1709,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
17091709
$animate.removeClass($element, PENDING_CLASS);
17101710
};
17111711

1712-
this.$$setPending = function(validationErrorKey, promise, currentValue) {
1712+
this.$$setPending = function(validationErrorKey, promise, modelValue, viewValue) {
17131713
ctrl.$pending = ctrl.$pending || {};
17141714
if (angular.isUndefined(ctrl.$pending[validationErrorKey])) {
17151715
ctrl.$pending[validationErrorKey] = true;
@@ -1725,19 +1725,19 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
17251725

17261726
//Special-case for (undefined|null|false|NaN) values to avoid
17271727
//having to compare each of them with each other
1728-
currentValue = currentValue || '';
1728+
viewValue = viewValue || '';
17291729
promise.then(resolve(true), resolve(false));
17301730

17311731
function resolve(bool) {
17321732
return function() {
17331733
var value = ctrl.$viewValue || '';
1734-
if (ctrl.$pending && ctrl.$pending[validationErrorKey] && currentValue === value) {
1734+
if (ctrl.$pending && ctrl.$pending[validationErrorKey] && viewValue === value) {
17351735
pendingCount--;
17361736
delete ctrl.$pending[validationErrorKey];
17371737
ctrl.$setValidity(validationErrorKey, bool);
17381738
if (pendingCount === 0) {
17391739
ctrl.$$clearPending();
1740-
ctrl.$$updateValidModelValue(value);
1740+
ctrl.$$updateValidModelValue(modelValue);
17411741
ctrl.$$writeModelToScope();
17421742
}
17431743
}
@@ -1947,7 +1947,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
19471947
throw $ngModelMinErr("$asyncValidators",
19481948
"Expected asynchronous validator to return a promise but got '{0}' instead.", result);
19491949
}
1950-
ctrl.$$setPending(validator, result, modelValue);
1950+
ctrl.$$setPending(validator, result, modelValue, viewValue);
19511951
});
19521952
}
19531953

test/ng/directive/inputSpec.js

+25
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,31 @@ describe('NgModelController', function() {
730730
dealoc(element);
731731
}));
732732

733+
it('should re-evaluate the form validity state against a parsed view value',
734+
inject(function($compile, $rootScope, $q) {
735+
var element = $compile('<form name="myForm">' +
736+
'<input type="number" name="curiousnumber" ng-model="curiousnumber" />' +
737+
'</form>')($rootScope);
738+
var inputElm = element.find('input');
739+
740+
var formCtrl = $rootScope.myForm;
741+
var curiousnumberCtrl = formCtrl.curiousnumber;
742+
var curiousnumberDefer;
743+
curiousnumberCtrl.$asyncValidators.isCurious = function() {
744+
curiousnumberDefer = $q.defer();
745+
return curiousnumberDefer.promise;
746+
};
747+
748+
curiousnumberCtrl.$setViewValue("22");
749+
$rootScope.$digest();
750+
expect(curiousnumberCtrl.$pending.isCurious).toBe(true);
751+
752+
curiousnumberDefer.resolve();
753+
$rootScope.$digest();
754+
expect(curiousnumberCtrl.$pending).toBeUndefined();
755+
756+
dealoc(element);
757+
}));
733758
});
734759
});
735760

0 commit comments

Comments
 (0)