diff --git a/packages/core/src/view/provider.ts b/packages/core/src/view/provider.ts index ca9ce4b4e6..ffd2c3966a 100644 --- a/packages/core/src/view/provider.ts +++ b/packages/core/src/view/provider.ts @@ -137,9 +137,15 @@ export function createDirectiveInstance(view: ViewData, def: NodeDef): any { if (def.outputs.length) { for (let i = 0; i < def.outputs.length; i++) { const output = def.outputs[i]; - const subscription = instance[output.propName !].subscribe( - eventHandlerClosure(view, def.parent !.nodeIndex, output.eventName)); - view.disposables ![def.outputIndex + i] = subscription.unsubscribe.bind(subscription); + const outputObservable = instance[output.propName !]; + if (typeof outputObservable === 'object') { + const subscription = outputObservable.subscribe( + eventHandlerClosure(view, def.parent !.nodeIndex, output.eventName)); + view.disposables ![def.outputIndex + i] = subscription.unsubscribe.bind(subscription); + } else { + throw new Error( + `@Output ${output.propName} not initialized in '${instance.constructor.name}'.`); + } } } return instance; diff --git a/packages/core/test/bundling/hello_world_r2/bundle.golden_symbols.json b/packages/core/test/bundling/hello_world_r2/bundle.golden_symbols.json index 8e32f0334d..96fd910e84 100644 --- a/packages/core/test/bundling/hello_world_r2/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hello_world_r2/bundle.golden_symbols.json @@ -3170,6 +3170,9 @@ { "name": "isObservable" }, + { + "name": "isObservable$1" + }, { "name": "isPrefixEnd" }, @@ -3839,4 +3842,4 @@ { "name": "wtfLeave" } -] \ No newline at end of file +] diff --git a/packages/core/test/linker/integration_spec.ts b/packages/core/test/linker/integration_spec.ts index 9a9d27c53b..fca61d50e2 100644 --- a/packages/core/test/linker/integration_spec.ts +++ b/packages/core/test/linker/integration_spec.ts @@ -346,6 +346,20 @@ function declareTests({useJit}: {useJit: boolean}) { expect(tc.injector.get(EventDir)).not.toBeNull(); }); + it('should display correct error message for uninitialized @Output', () => { + @Directive({selector: '[uninitializedOuput]'}) + class UninitializedOuput { + @Output() customEvent; + doSomething() { + } + } + + TestBed.configureTestingModule({declarations: [MyComp, UninitializedOuput]}); + const template = '
'; + TestBed.overrideComponent(MyComp, {set: {template}}); + TestBed.createComponent(MyComp).toThrowError('@Output customEvent not initialized in \'UninitializedOuput\'.'); + }); + it('should read directives metadata from their binding token', () => { TestBed.configureTestingModule({declarations: [MyComp, PrivateImpl, NeedsPublicApi]}); const template = '