codejump

AcademyAngular

Event Binding and Custom Outputs

(event)="handler($event)" binds a native DOM event; @Output() lets a component emit its own, typed the same way any other value in the app is typed.

2 min readUpdated

3 exercises

Waiting at the end of this page.

Parentheses bind an event; $event is whatever it carries

(event)="expression" wires a native DOM event to a template expression, and $event inside that expression is the event object the browser fired — a KeyboardEvent, a MouseEvent, whatever the event name implies:

HTML
<form (submit)="onSubmit($event)">
  <input (keydown.enter)="addTodo($event)" />
</form>

A form that reloads the page on Enter is almost always this: the handler runs, but nothing called $event.preventDefault() first, so the browser's default submit-and-navigate behavior fires right alongside the component's own logic. The fix is never "stop using (submit)" — it is calling preventDefault() as the first line of the handler, the same instinct as in any framework-free DOM code.

@Output() makes a component's own events, typed

A child component emits upward through an @Output() property, conventionally an EventEmitter:

typescript
@Output() rate = new EventEmitter<number>();

onStarClick(value: number): void {
  this.rate.emit(value);
}

<app-star-rating (rate)="onRate($event)" /> in the parent then receives whatever the child .emit()s as its own $event — the mechanism is identical to a native DOM event, which is precisely the point: @Output() exists to make a custom event indistinguishable, from the template's perspective, from click or submit.

A typed union output has to emit every branch it declares

Once an output's generic is a union — EventEmitter<{ status: 'success' } | { status: 'error'; message: string }> — TypeScript will happily let a handler compile while only ever emitting the success branch; nothing forces every code path that can fail to actually call .emit() with the error shape. That gap does not show up as a type error, because the emitter's declared type is correct — only its call sites are incomplete, and finding that requires reading what triggers the failure path, not just what the type declares.

What interviewers check

Whether you reach for $event.preventDefault() before you reach for a workaround, and whether you can explain @Output()/EventEmitter as "the same idea as a native DOM event, just declared by application code" rather than as a separate mechanism to memorize.

Now practice it

1 quiz · 2 drills

Reading this page is the cheap half. These are the exercises that make you use it.