Kevin Paul Tracy
Kevin Paul Tracy

Reputation: 185

Event Emitter Binding

I am going through "Angular Up and Running" by Shyam Seshadri, published by O'Reilly. In the discussion on Output and the emitting of events I'm a little confused.

The EventEmitter in a component is declared, initialized and implemented as:

@Output() private toggleFavorite: EventEmitter<Stock>;

constructor() {
 this.toggleFavorite = new EventEmitter<Stock>();
}

onToggleFavorite(event) {
 console.log('We are toggling the favorite state for this stock.', event);
 this.toggleFavorite.emit(this.stock);
}

The binding in the app.component.html reads:

(toggleFavorite)="appToggleFavorite($event)"

But the method in app.component.ts is defined as:

appToggleFavorite(stock: Stock) {
 console.log('Favorite for stock ', stock, ' was triggered.');
}

If the binding is passing the $event object, and the bound method is expecting a Stock type, why does this work?

(And it does work, I've tested it.)

I am not asking what the $event object does, I already know that. Please re-read my question above carefully. I am asking: when a bound function is expecting a typed parameter, why is a binding to an EventEmitter object passing the $event object instead of an object of the expected type, and why does it seem to work (the parameter gets it's values as typed.)

Upvotes: 2

Views: 3667

Answers (3)

Gaspar
Gaspar

Reputation: 1601

It's a Advanced Type of TypeScript, not from Angular. When you declare:

@Output() private toggleFavorite: EventEmitter<Stock>;

The type of toggleFavorite is <Stock> and the compiler is "waiting" this type in return of value.
The doc of this is right here.

Upvotes: 0

SiddAjmera
SiddAjmera

Reputation: 39482

My best guess would be, carefully have a look at the appToggleFavorite function below.

appToggleFavorite(stock: Stock) {
 console.log('Favorite for stock ', stock, ' was triggered.');
}

If it were to be called at Compile time, it would have thrown an error saying that appToggleFavorite is expecting an arg of type Stock but isn't given one.

But appToggleFavorite is getting called at runtime, and at runtime, its just HTML and JavaScript. It doesn't care what is received as an arg to appToggleFavorite. And thus it works.

Just to give you a brief, the Child Component can let the Parent Component know about something via an Output property on it. This Output property will then be used by the Parent Component's Template as an event. So to listen for the Output property, an Event Binding would be required. The Handler Function that is assigned to this Event Binding will be called as soon as the emit method is called on the EventEmitter that was exposed as an Output property. The Handler function will only be able to get a hold of the data that was passed to the emit function only if the reserved keyword $event is used.

Upvotes: 0

JFPicard
JFPicard

Reputation: 5168

Technically, the $event is unecessary and create confusion.

(toggleFavorite)="appToggleFavorite()"

will work as well, since you're implying that when you call .emit, you will call appToggleFavorite with any value type given to .emit. And Javascript is an untyped language, so it will work at run time.

Upvotes: 2

Related Questions