Event Binding

Parentheses bind a template event — a click, a keystroke, a form submission — to a method on the component class.

Handling a click

TS counter.component.ts
export class CounterComponent {
  count = 0;

  increment() {
    this.count++;
  }
}
HTML counter.component.html
<p>Count: {{ count }}</p>
<button (click)="increment()">+1</button>
Behavior
Each click on the button calls increment(), which
updates count — and the {{ count }} display updates
automatically, with no manual DOM code required.

(click)="increment()" reads as "when the click event fires, run increment()." Angular handles reflecting the changed count back into the template on its own.

Passing the event object

TS search.component.ts
export class SearchComponent {
  onKeyUp(event: KeyboardEvent) {
    const input = event.target as HTMLInputElement;
    console.log('Typed so far:', input.value);
  }
}
HTML search.component.html
<input (keyup)="onKeyUp($event)" placeholder="Search...">
Console output while typing "hi"
Typed so far: h
Typed so far: hi

$event is a special Angular template variable that always refers to whatever event object the handler was called with — here, the native browser KeyboardEvent, from which event.target gets you the actual input element.

Two-way binding revisited

Now that both halves are familiar, [(ngModel)]="query" from the previous lesson can be understood as sugar for exactly this pattern combined:

HTML equivalent, spelled out
<input [ngModel]="query" (ngModelChange)="query = $event">

[ngModel]="query" is the property binding half (class → input), and (ngModelChange)="query = $event" is the event binding half (input → class). [( )] is just shorthand for writing both together.

Note: a method called from a template, like increment() or onKeyUp(), runs inside the component's own this context automatically — you never need .bind(this) the way you sometimes do with plain JavaScript callbacks. Where people do get tripped up is passing a method as a bare reference instead of calling it, e.g. writing (click)="increment" without the parentheses — that does nothing, since it's not a valid event-binding expression rather than a call.