Angular Events

Event binding wires DOM events like clicks and keystrokes to methods on your component class using parentheses syntax.

Binding to the click Event

Wrapping an event name in parentheses tells Angular to listen for that native DOM event and run the given expression when it fires. The most common example is (click), which calls a component method whenever the user clicks the bound element.

A counter driven by click events

import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';

@Component({
  selector: 'app-counter',
  standalone: true,
  template: `
    <button (click)="decrement()">-</button>
    <span>{{ count }}</span>
    <button (click)="increment()">+</button>
  `
})
export class CounterComponent {
  count = 0;

  increment() {
    this.count++;
  }

  decrement() {
    this.count--;
  }
}

bootstrapApplication(CounterComponent).catch((err) => console.error(err));

The $event Object

Angular passes the native DOM event object into your handler through the special $event variable, giving you access to details like the key pressed, the mouse position, or the input's current value. This is essential for anything beyond a simple no-argument click.

Reading input value and key events

import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';

@Component({
  selector: 'app-quick-search',
  standalone: true,
  template: `
    <input
      (input)="onInput($event)"
      (keydown.enter)="onSubmit()"
      placeholder="Type to search"
    />
    <p>Current text: {{ currentText }}</p>
  `
})
export class QuickSearchComponent {
  currentText = '';

  onInput(event: Event) {
    this.currentText = (event.target as HTMLInputElement).value;
  }

  onSubmit() {
    console.log('Searching for', this.currentText);
  }
}

bootstrapApplication(QuickSearchComponent).catch((err) => console.error(err));

Custom Events with @Output

Components can emit their own custom events using @Output combined with an EventEmitter, letting a child notify its parent about something that happened without the parent needing to poll for changes.

A child component emitting a custom event

import { Component, EventEmitter, Output } from '@angular/core';
import { CommonModule } from '@angular/common';
import { bootstrapApplication } from '@angular/platform-browser';

@Component({
  selector: 'app-rating',
  standalone: true,
  imports: [CommonModule],
  template: `
    <button *ngFor="let n of [1,2,3,4,5]" (click)="rate(n)">
      {{ n <= selected ? '★' : '☆' }}
    </button>
  `
})
export class RatingComponent {
  selected = 0;
  @Output() rated = new EventEmitter<number>();

  rate(value: number) {
    this.selected = value;
    this.rated.emit(value);
  }
}

bootstrapApplication(RatingComponent).catch((err) => console.error(err));
SyntaxFires when
(click)The element is clicked
(input)A form control's value changes as the user types
(keydown.enter)The Enter key is pressed while the element has focus
(submit)A form is submitted
(customEvent)A child component calls emit() on a matching @Output
  • Event bindings never use $ or brackets around the event name, only parentheses.
  • Angular supports key-modifier events like (keydown.enter) and (keyup.escape) directly in the template.
  • Custom @Output events are named without the word 'on', by convention: rated, not onRated.
  • Always type EventEmitter with a generic, e.g. EventEmitter<number>, so consumers get type-checked payloads.
Note: You can call event.preventDefault() and event.stopPropagation() directly from a handler by passing $event, exactly as you would in vanilla JavaScript.
Note: Binding an event to a method call that itself returns a value, like (click)="save()", ignores that return value — Angular treats the expression only for its side effect, never for what it evaluates to.

Exercise: Angular Events

How is a click handler bound to a button in a template?