Skip to content

Commit d0f7829

Browse files
committed
fix($parse): treat falsy values as defined in assignment expressions
Closes angular#14990 Closes angular#14994
1 parent 138fbf0 commit d0f7829

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

src/ng/parse.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,7 @@ ASTCompiler.prototype = {
944944
self.if_(self.stage === 'inputs' || 's', function() {
945945
if (create && create !== 1) {
946946
self.if_(
947-
self.not(self.nonComputedMember('s', ast.name)),
947+
self.isNull(self.nonComputedMember('s', ast.name)),
948948
self.lazyAssign(self.nonComputedMember('s', ast.name), '{}'));
949949
}
950950
self.assign(intoId, self.nonComputedMember('s', ast.name));
@@ -973,7 +973,7 @@ ASTCompiler.prototype = {
973973
}
974974
} else {
975975
if (create && create !== 1) {
976-
self.if_(self.not(self.nonComputedMember(left, ast.property.name)), self.lazyAssign(self.nonComputedMember(left, ast.property.name), '{}'));
976+
self.if_(self.isNull(self.nonComputedMember(left, ast.property.name)), self.lazyAssign(self.nonComputedMember(left, ast.property.name), '{}'));
977977
}
978978
expression = self.nonComputedMember(left, ast.property.name);
979979
self.assign(intoId, expression);
@@ -1155,6 +1155,10 @@ ASTCompiler.prototype = {
11551155
return '!(' + expression + ')';
11561156
},
11571157

1158+
isNull: function(expression) {
1159+
return expression + '==null';
1160+
},
1161+
11581162
notNull: function(expression) {
11591163
return expression + '!=null';
11601164
},
@@ -1546,7 +1550,7 @@ ASTInterpreter.prototype = {
15461550
identifier: function(name, context, create, expression) {
15471551
return function(scope, locals, assign, inputs) {
15481552
var base = locals && (name in locals) ? locals : scope;
1549-
if (create && create !== 1 && base && !(base[name])) {
1553+
if (create && create !== 1 && base && base[name] == null) {
15501554
base[name] = {};
15511555
}
15521556
var value = base ? base[name] : undefined;
@@ -1583,7 +1587,7 @@ ASTInterpreter.prototype = {
15831587
return function(scope, locals, assign, inputs) {
15841588
var lhs = left(scope, locals, assign, inputs);
15851589
if (create && create !== 1) {
1586-
if (lhs && !(lhs[right])) {
1590+
if (lhs && lhs[right] == null) {
15871591
lhs[right] = {};
15881592
}
15891593
}

test/ng/parseSpec.js

+39
Original file line numberDiff line numberDiff line change
@@ -3155,6 +3155,45 @@ describe('parser', function() {
31553155
expect(isFunction(s.toString)).toBe(true);
31563156
expect(l.toString).toBe(1);
31573157
}));
3158+
3159+
it('should assign a property to scope properties with null or undefined value', inject(function($parse) {
3160+
var scope = {a:null};
3161+
$parse('a.b =1')(scope);
3162+
expect(scope.a).toEqual({b:1});
3163+
3164+
scope.a = undefined;
3165+
$parse('a.b =1')(scope);
3166+
expect(scope.a).toEqual({b:1});
3167+
}));
3168+
3169+
they('should not assign a property to scope properties with $prop value', [0, false, ''],
3170+
function(falsyValue) {
3171+
inject(function($parse) {
3172+
var scope = {a:falsyValue};
3173+
expect(function() {
3174+
$parse('a.b=1')(scope);
3175+
}).toThrow();
3176+
expect(scope.a).toBe(falsyValue);
3177+
3178+
scope = {a:falsyValue};
3179+
expect(function() {
3180+
$parse('a[\'b\']=1')(scope);
3181+
}).toThrow();
3182+
expect(scope.a).toBe(falsyValue);
3183+
3184+
scope = {a:{b:falsyValue}};
3185+
expect(function() {
3186+
$parse('a.b.c=1')(scope);
3187+
}).toThrow();
3188+
expect(scope.a.b).toBe(falsyValue);
3189+
3190+
scope = {a:{b:falsyValue}};
3191+
expect(function() {
3192+
$parse('a.b[\'c\']=1')(scope);
3193+
}).toThrow();
3194+
expect(scope.a.b).toBe(falsyValue);
3195+
});
3196+
});
31583197
});
31593198

31603199
describe('literal', function() {

0 commit comments

Comments
 (0)