AngularJSEvent Binding

Event Binding in Angular

Event binding lets your component respond to user actions — clicks, key presses, mouse movements, form submissions, and more. The parentheses syntax (eventName)="handler()" means "when this event fires, call this handler in the component class."

Event binding is a one-way flow: data travels from the template to the component class.

Basic Syntax

TS
import { Component } from '@angular/core';

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

  increment() { this.count++; }
  decrement() { this.count--; }
  reset()     { this.count = 0; }
}
Note
The expression inside the quotes is executed as a TypeScript statement, not evaluated as a value. You can call methods, assign variables, or write simple inline statements like \`count = 0\`.
The $event Object

Angular exposes the native DOM event object as $event. Pass it to your handler when you need event details like the key pressed, mouse coordinates, or the target element's value.

TS
@Component({
  selector: 'app-event-demo',
  standalone: true,
  template: `
    <!-- Pass $event for full event details -->
    <input (input)="onInput($event)" placeholder="Type here" />
    <p>You typed: {{ typedText }}</p>

    <!-- Mouse position -->
    <div class="canvas" (mousemove)="onMouseMove($event)">
      Move mouse here
    </div>
    <p>Mouse: {{ mouseX }}, {{ mouseY }}</p>

    <!-- Form submit -->
    <form (submit)="onSubmit($event)">
      <button type="submit">Submit</button>
    </form>
  `,
})
export class EventDemoComponent {
  typedText = '';
  mouseX = 0;
  mouseY = 0;

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

  onMouseMove(event: MouseEvent) {
    this.mouseX = event.clientX;
    this.mouseY = event.clientY;
  }

  onSubmit(event: SubmitEvent) {
    event.preventDefault();
    console.log('Form submitted');
  }
}
Inline Statements

For simple cases, you can write a short statement directly in the template without defining a method. This is fine for one-liners but prefer named methods for anything involving logic.

HTML
<!-- Inline assignment -->
<button (click)="isVisible = !isVisible">Toggle</button>

<!-- Inline method with argument -->
<button (click)="removeItem(item.id)">Delete</button>

<!-- Multiple statements (not recommended — hard to read) -->
<button (click)="count = count + 1; lastClicked = 'increment'">+</button>

<!-- Accessing $event inline -->
<input (keyup)="lastKey = $event.key" />
Tip
Keep inline template statements short. If an expression needs more than one operation, move it to a component method for readability and testability.
Keyboard Event Filtering

Angular supports key event filtering directly in the binding syntax using dot notation. This saves you from writing if (event.key === 'Enter') inside your handler.

TS
@Component({
  selector: 'app-search',
  standalone: true,
  template: `
    <!-- Only fires on Enter key -->
    <input (keyup.enter)="search()" [(ngModel)]="query" />

    <!-- Specific key combinations -->
    <textarea (keydown.control.s)="save($event)" placeholder="Edit content"></textarea>
    <input (keydown.escape)="clearInput()" [(ngModel)]="text" />

    <!-- Arrow keys -->
    <div (keydown.arrowUp)="moveUp()" (keydown.arrowDown)="moveDown()" tabindex="0">
      Navigate with arrow keys
    </div>
  `,
})
export class SearchComponent {
  query = '';
  text = '';

  search() {
    console.log('Searching for:', this.query);
  }

  save(event: KeyboardEvent) {
    event.preventDefault();
    console.log('Saved!');
  }

  clearInput() { this.text = ''; }
  moveUp()     { console.log('Moving up'); }
  moveDown()   { console.log('Moving down'); }
}
Common DOM Events

Event

Binding

When It Fires

click

(click)

Mouse button pressed and released

dblclick

(dblclick)

Double click

mouseover

(mouseover)

Mouse enters element

mouseout

(mouseout)

Mouse leaves element

mousemove

(mousemove)

Mouse moves over element

keydown

(keydown)

Key pressed down

keyup

(keyup)

Key released

input

(input)

Input value changed (every keystroke)

change

(change)

Input value committed (on blur)

focus

(focus)

Element receives focus

blur

(blur)

Element loses focus

submit

(submit)

Form submitted

scroll

(scroll)

Element scrolled

Component Event Binding with @Output

Child components emit custom events via @Output() and EventEmitter. The parent binds to these custom events with the same parentheses syntax used for DOM events.

TS
// child: like-button.component.ts
import { Component, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-like-button',
  standalone: true,
  template: `
    <button (click)="toggle()">
      {{ liked ? 'Unlike' : 'Like' }} ({{ likeCount }})
    </button>
  `,
})
export class LikeButtonComponent {
  @Output() likeChanged = new EventEmitter<{ liked: boolean; count: number }>();

  liked = false;
  likeCount = 42;

  toggle() {
    this.liked = !this.liked;
    this.likeCount += this.liked ? 1 : -1;
    this.likeChanged.emit({ liked: this.liked, count: this.likeCount });
  }
}

TS
// parent component
@Component({
  selector: 'app-post',
  standalone: true,
  imports: [LikeButtonComponent],
  template: `
    <app-like-button (likeChanged)="onLikeChanged($event)" />
    <p>Status: {{ likeStatus }}</p>
  `,
})
export class PostComponent {
  likeStatus = '';

  onLikeChanged(data: { liked: boolean; count: number }) {
    this.likeStatus = data.liked
      ? `Liked! Total: ${data.count}`
      : `Unliked. Total: ${data.count}`;
  }
}
Stopping Event Propagation

Use $event.stopPropagation() to prevent an event from bubbling up to parent elements, and $event.preventDefault() to block the browser's default behaviour.

HTML
<!-- Stop click from bubbling to parent overlay -->
<div class="overlay" (click)="closeModal()">
  <div class="modal" (click)="$event.stopPropagation()">
    Modal content — clicking here won't close the overlay
  </div>
</div>

<!-- Prevent default link navigation -->
<a href="/old-path" (click)="navigate($event)">Custom navigation</a>

<!-- Prevent form default submission -->
<form (submit)="handleSubmit($event)">
  <button type="submit">Submit</button>
</form>
Event Binding in Loops

Inside @for or *ngFor, pass the item as an argument to the handler to identify which item was acted upon.

TS
@Component({
  selector: 'app-todo-list',
  standalone: true,
  template: `
    <ul>
      @for (item of items; track item.id) {
        <li>
          <span [class.done]="item.done">{{ item.text }}</span>
          <button (click)="toggle(item)">Toggle</button>
          <button (click)="remove(item.id)">Delete</button>
        </li>
      }
    </ul>
    <button (click)="addItem()">Add Item</button>
  `,
})
export class TodoListComponent {
  items = [
    { id: 1, text: 'Learn Angular', done: false },
    { id: 2, text: 'Build an app', done: false },
  ];

  toggle(item: { id: number; text: string; done: boolean }) {
    item.done = !item.done;
  }

  remove(id: number) {
    this.items = this.items.filter(i => i.id !== id);
  }

  addItem() {
    const id = Date.now();
    this.items.push({ id, text: `New item ${id}`, done: false });
  }
}
Warning
Avoid passing \`\$event\` and item arguments together when you do not need the event object — it adds unnecessary coupling between template and handler signature.
Summary
  • (eventName)="handler()" — calls a method when a DOM or custom event fires.

  • $event is the native event object — pass it when you need event details.

  • Inline statements like (click)="count++" are fine for trivial cases.

  • Angular key filtering: (keyup.enter), (keydown.control.s), (keydown.escape).

  • Child components emit custom events via @Output + EventEmitter; parent binds with (customEvent).

  • Use $event.stopPropagation() and $event.preventDefault() for fine-grained control.

  • In loops, pass the item as a method argument to identify which item was acted upon.