fix(core): throw error message when @Output not initialized (#19116)

Closes #3664

PR Close #19116
This commit is contained in:
Aldo Roman 2017-09-08 18:41:13 -05:00 committed by Igor Minar
parent 74bce18190
commit adf510f986
3 changed files with 27 additions and 4 deletions

View File

@ -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;

View File

@ -3170,6 +3170,9 @@
{
"name": "isObservable"
},
{
"name": "isObservable$1"
},
{
"name": "isPrefixEnd"
},

View File

@ -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 = '<p (customEvent)="doNothing()"></p>';
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 = '<div public-api><div needs-public-api></div></div>';