From f31c9470fae06adc69b2b665773bfc0a8a10d10e Mon Sep 17 00:00:00 2001 From: Chuck Jazdzewski Date: Tue, 6 Dec 2016 10:40:15 -0800 Subject: [PATCH] fix(compiler): short-circut expressions with an index (#13263) Fixes #13254 --- .../compiler/src/compiler_util/expression_converter.ts | 9 +++++++-- .../test/linker/change_detection_integration_spec.ts | 7 +++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/modules/@angular/compiler/src/compiler_util/expression_converter.ts b/modules/@angular/compiler/src/compiler_util/expression_converter.ts index 0bdab279f4..d5e0f7becd 100644 --- a/modules/@angular/compiler/src/compiler_util/expression_converter.ts +++ b/modules/@angular/compiler/src/compiler_util/expression_converter.ts @@ -284,8 +284,13 @@ class _AstToIrVisitor implements cdAst.AstVisitor { } visitKeyedRead(ast: cdAst.KeyedRead, mode: _Mode): any { - return convertToStatementIfNeeded( - mode, this.visit(ast.obj, _Mode.Expression).key(this.visit(ast.key, _Mode.Expression))); + const leftMostSafe = this.leftMostSafeNode(ast); + if (leftMostSafe) { + return this.convertSafeAccess(ast, leftMostSafe, mode); + } else { + return convertToStatementIfNeeded( + mode, this.visit(ast.obj, _Mode.Expression).key(this.visit(ast.key, _Mode.Expression))); + } } visitKeyedWrite(ast: cdAst.KeyedWrite, mode: _Mode): any { diff --git a/modules/@angular/core/test/linker/change_detection_integration_spec.ts b/modules/@angular/core/test/linker/change_detection_integration_spec.ts index 7c4e04a845..8dafcd53e7 100644 --- a/modules/@angular/core/test/linker/change_detection_integration_spec.ts +++ b/modules/@angular/core/test/linker/change_detection_integration_spec.ts @@ -305,6 +305,12 @@ export function main() { expect(renderLog.log).toEqual(['someProp=null']); })); + it('should support short-circuting array index operations', fakeAsync(() => { + const ctx = _bindSimpleValue('value?.phones[0]', PersonHolder); + ctx.detectChanges(false); + expect(renderLog.log).toEqual(['someProp=null']); + })); + it('should still throw if right-side would throw', fakeAsync(() => { expect(() => { const ctx = _bindSimpleValue('value?.address.city', PersonHolder); @@ -1515,6 +1521,7 @@ class Person { age: number; name: string; address: Address = null; + phones: number[]; init(name: string, address: Address = null) { this.name = name;