Skip to content

Commit a95d652

Browse files
chuckjazIgorMinar
authored andcommitted
fix(compiler): Safe property access expressions work in event bindings (#11724)
1 parent fdb22bd commit a95d652

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

modules/@angular/compiler/src/view_compiler/expression_converter.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
340340
// Notice that the first guard condition is the left hand of the left most safe access node
341341
// which comes in as leftMostSafe to this routine.
342342

343-
let guardedExpression = this.visit(leftMostSafe.receiver, mode);
343+
let guardedExpression = this.visit(leftMostSafe.receiver, _Mode.Expression);
344344
let temporary: o.ReadVarExpr;
345345
if (this.needsTemporary(leftMostSafe.receiver)) {
346346
// If the expression has method calls or pipes then we need to save the result into a
@@ -369,7 +369,7 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
369369
}
370370

371371
// Recursively convert the node now without the guarded member access.
372-
const access = this.visit(ast, mode);
372+
const access = this.visit(ast, _Mode.Expression);
373373

374374
// Remove the mapping. This is not strictly required as the converter only traverses each node
375375
// once but is safer if the conversion is changed to traverse the nodes more than once.
@@ -381,7 +381,7 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
381381
}
382382

383383
// Produce the conditional
384-
return condition.conditional(o.literal(null), access);
384+
return convertToStatementIfNeeded(mode, condition.conditional(o.literal(null), access));
385385
}
386386

387387
// Given a expression of the form a?.b.c?.d.e the the left most safe node is

modules/@angular/core/test/linker/regression_integration_spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,24 @@ function declareTests({useJit}: {useJit: boolean}) {
7979
expect(fixture.nativeElement).toHaveText('counting method value');
8080
expect(MyCountingComp.calls).toBe(1);
8181
});
82+
83+
it('should evalute a conditional in a statement binding', () => {
84+
@Component({selector: 'some-comp', template: '<p (click)="nullValue?.click()"></p>'})
85+
class SomeComponent {
86+
nullValue: SomeReferencedClass;
87+
}
88+
89+
class SomeReferencedClass {
90+
click() {}
91+
}
92+
93+
expect(() => {
94+
const fixture = TestBed.configureTestingModule({declarations: [SomeComponent]})
95+
.createComponent(SomeComponent);
96+
97+
fixture.detectChanges(/* checkNoChanges */ false);
98+
}).not.toThrow();
99+
});
82100
});
83101

84102
describe('providers', () => {

0 commit comments

Comments
 (0)