Skip to content
Permalink
Browse files

fix(ngModel): treat synchronous validators as boolean always

Change synchronous validators to convert the return to boolean value.
Prevent unexpected behavior when returning `undefined`.

Closes #14734
Closes #15208

BREAKING CHANGE: Previously, only a literal `false` return would resolve as the
synchronous validator failing. Now, all traditionally false JavaScript values
are treated as failing the validator, as one would naturally expect.

Specifically, the values `0` (the number zero), `null`, `NaN` and `''` (the
empty string) used to considered valid (passing) and they are now considered
invalid (failing). The value `undefined` was treated similarly to a pending
asynchronous validator, causing the validation to be pending. `undefined` is
also now considered invalid.

To migrate, make sure your synchronous validators are returning either a
literal `true` or a literal `false` value. For most code, we expect this to
already be the case. Only a very small subset of projects will be affected.

Namely, anyone using `undefined` or any falsy value as a return will now see
their validation failing, whereas previously falsy values other than `undefined`
would have been seen as passing and `undefined` would have been seen as pending.
  • Loading branch information
BobChao87 authored and petebacondarwin committed Oct 4, 2016
1 parent e8aebb3 commit 7bc71adc63bb6bb609b44dd2d3ea8fb0cd3f300b
Showing with 27 additions and 1 deletion.
  1. +1 −1 src/ng/directive/ngModel.js
  2. +26 −0 test/ng/directive/ngModelSpec.js
@@ -603,7 +603,7 @@ NgModelController.prototype = {
function processSyncValidators() {
var syncValidatorsValid = true;
forEach(that.$validators, function(validator, name) {
var result = validator(modelValue, viewValue);
var result = Boolean(validator(modelValue, viewValue));
syncValidatorsValid = syncValidatorsValid && result;
setValidity(name, result);
});
@@ -847,6 +847,32 @@ describe('ngModel', function() {
expect(ctrl.$valid).toBe(true);
});

it('should treat all responses as boolean for synchronous validators', function() {
var expectValid = function(value, expected) {
ctrl.$modelValue = undefined;
ctrl.$validators.a = valueFn(value);

ctrl.$validate();
expect(ctrl.$valid).toBe(expected);
};

// False tests
expectValid(false, false);
expectValid(undefined, false);
expectValid(null, false);
expectValid(0, false);
expectValid(NaN, false);
expectValid('', false);

// True tests
expectValid(true, true);
expectValid(1, true);
expectValid('0', true);
expectValid('false', true);
expectValid([], true);
expectValid({}, true);
});


it('should register invalid validations on the $error object', function() {
var curry = function(v) {

0 comments on commit 7bc71ad

Please sign in to comment.
You can’t perform that action at this time.