Skip to content

Angular Event Binding

Event binding is how Angular templates respond to user interaction: clicks, key presses, form submissions, and custom component events. This lesson covers the syntax and common patterns you will use constantly.

What Is Event Binding?

Event binding connects a DOM event (or a custom component event) to a method or statement on the component class. Angular wraps parentheses around the event name and evaluates the expression whenever that event fires.

Event binding is how Angular templates stay reactive to user input without manually attaching and removing addEventListener calls.

@Component({
  selector: 'app-like-button',
  standalone: true,
  template: `
    <button (click)="toggleLike()">
      {{ liked ? 'Liked' : 'Like' }}
    </button>
  `,
})
export class LikeButtonComponent {
  liked = false;
  toggleLike() {
    this.liked = !this.liked;
  }
}

Clicking the button runs toggleLike(), which flips the liked flag and Angular re-renders the button text automatically.

Event Binding Syntax

(event)="statement"
(event)="method($event)"
(keydown.enter)="onEnter()"
  • Wrap the event name in parentheses; the right-hand side is a statement, not just an expression.
  • $event gives access to the native event object (or an emitted value for custom outputs).
  • Key events support dot-notation modifiers like .enter, .escape, or .shift.enter.
  • Multiple statements can be separated with semicolons, though a single method call is usually clearer.

Angular Event Binding Cheatsheet

Common events and patterns you will bind to in Angular templates.

Binding Example Fires On
Click (click)="save()" Mouse click
Input (input)="onInput($event)" Every keystroke in a text input
Change (change)="onChange($event)" Value committed (blur/select change)
Submit (submit)="onSubmit()" Form submission
Key modifier (keydown.enter)="search()" Enter key pressed
Focus/blur (focus)="...", (blur)="..." Focus gained/lost
Custom output (itemSelected)="onSelect($event)" Emitted by a child component

Working With $event

$event gives access to whatever the event carries. For native DOM events, it's the standard Event (or a subtype like KeyboardEvent); for a custom Angular output, it's whatever value was passed to .emit().

<input (input)="onSearch($event)" />

Reading Input Values

onSearch(event: Event) {
  const value = (event.target as HTMLInputElement).value;
  this.searchTerm = value;
}

Casting event.target to HTMLInputElement gives you typed access to .value in TypeScript.

Key Event Modifiers

Instead of checking event.key manually inside a handler, Angular lets you filter key events directly in the template using dot-notation modifiers.

<input
  (keydown.enter)="submit()"
  (keydown.escape)="cancel()"
  (keydown.control.s)="save()"
/>

Listening to Custom Component Events

Event binding syntax works identically for custom outputs declared on child components with @Output() or the newer output() function, not just native DOM events.

<app-rating (ratingChange)="onRatingChange($event)"></app-rating>

Common Mistakes

  • Forgetting to cast event.target when reading input values, causing TypeScript errors on .value.
  • Attaching heavy logic directly in (input) handlers on every keystroke without debouncing.
  • Confusing (input) (fires on every keystroke) with (change) (fires when the value is committed).
  • Manually parsing key codes instead of using Angular's built-in key modifiers like .enter or .escape.

Key Takeaways

  • Event binding uses parentheses and runs a statement whenever the named event fires.
  • $event exposes the native event object or an emitted custom value.
  • Key modifiers like .enter and .escape filter keyboard events directly in the template.
  • The same (eventName) syntax works for both native DOM events and custom component outputs.

Pro Tip

For frequent events like (input), debounce expensive work (like an API call) in the component class rather than firing it on every keystroke, RxJS's debounceTime operator is a natural fit here.