diff --git a/packages/common/test/directives/ng_template_outlet_spec.ts b/packages/common/test/directives/ng_template_outlet_spec.ts
index 9226e5acbe..4f349b1776 100644
--- a/packages/common/test/directives/ng_template_outlet_spec.ts
+++ b/packages/common/test/directives/ng_template_outlet_spec.ts
@@ -204,6 +204,20 @@ describe('NgTemplateOutlet', () => {
fixture.componentInstance.value = 'baz';
detectChangesAndExpectText('');
});
+
+ // https://github.com/angular/angular/issues/30801
+ it('should not throw if the context is left blank', () => {
+ const template = `
+ test
+
+ `;
+
+ expect(() => {
+ fixture = createTestComponent(template);
+ detectChangesAndExpectText('test');
+ }).not.toThrow();
+ });
+
});
@Injectable()
diff --git a/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts b/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts
index 82b4379423..78b52bc5a4 100644
--- a/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts
+++ b/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts
@@ -2932,6 +2932,28 @@ describe('compiler compliance', () => {
expectEmit(source, SomeDirectiveDefinition, 'Incorrect SomeDirective.ngDirectiveDef');
});
+ it('should not throw for empty property bindings on ng-template', () => {
+ const files = {
+ app: {
+ 'example.ts': `
+ import {Component, NgModule} from '@angular/core';
+
+ @Component({
+ selector: 'my-app',
+ template: ''
+ })
+ export class MyComponent {
+ }
+
+ @NgModule({declarations: [MyComponent]})
+ export class MyModule {}`
+ }
+ };
+
+ expect(() => compile(files, angularFiles)).not.toThrow();
+ });
+
+
});
describe('inherited base classes', () => {
diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts
index d7316a84af..2a742933b4 100644
--- a/packages/compiler/src/render3/view/template.ts
+++ b/packages/compiler/src/render3/view/template.ts
@@ -1024,10 +1024,13 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver
attrs.forEach(input => {
if (input instanceof t.BoundAttribute) {
const value = input.value.visit(this._valueConverter);
- this.allocateBindingSlots(value);
- this.updateInstruction(
- templateIndex, template.sourceSpan, R3.property,
- () => [o.literal(input.name), this.convertPropertyBinding(context, value, true)]);
+
+ if (value !== undefined) {
+ this.allocateBindingSlots(value);
+ this.updateInstruction(
+ templateIndex, template.sourceSpan, R3.property,
+ () => [o.literal(input.name), this.convertPropertyBinding(context, value, true)]);
+ }
}
});
}