Event binding connects DOM events to component methods. Every browser event — from a click to a keyboard shortcut — can be handled with the (event)="handler($event)" syntax. The $event object provides the raw browser event data: mouse position, key pressed, input value, form state. Angular also provides event filtering shortcuts like (keydown.enter) that trigger only for specific key combinations, eliminating manual key code checks.
Event Binding Patterns
@Component({
selector: 'app-search-bar',
standalone: true,
template: `
<form (submit)="onSearch($event)">
<!-- Input event — fires on every keystroke ────────────────────────── -->
<input
type="text"
[value]="searchQuery"
(input)="onInput($event)"
(focus)="onFocus()"
(blur)="onBlur()"
(keydown.enter)="onSearch($event)" <!-- only fires for Enter key ── -->
(keydown.escape)="clearSearch()" <!-- only fires for Escape ───── -->
placeholder="Search posts..."
>
<!-- Click with event details ─────────────────────────────────────── -->
<button type="button" (click)="onClear($event)">×</button>
<button type="submit">Search</button>
</form>
<!-- Mouse events ─────────────────────────────────────────────────── -->
<div
(mouseover)="onHover(true)"
(mouseleave)="onHover(false)"
(dblclick)="onDoubleClick()"
></div>
`,
})
export class SearchBarComponent {
searchQuery = signal('');
isFocused = signal(false);
onInput(event: Event): void {
// Cast $event to the specific event type for type safety
const input = event.target as HTMLInputElement;
this.searchQuery.set(input.value);
}
onSearch(event: Event): void {
event.preventDefault(); // prevent page reload on form submit
if (this.searchQuery().trim())
console.log('Searching for:', this.searchQuery());
}
onClear(event: MouseEvent): void {
event.stopPropagation(); // prevent click from bubbling to parent
this.searchQuery.set('');
}
onFocus(): void { this.isFocused.set(true); }
onBlur(): void { this.isFocused.set(false); }
onHover(hovered: boolean): void { /* update hover state */ }
onDoubleClick(): void { /* handle double click */ }
clearSearch(): void { this.searchQuery.set(''); }
}
addEventListener — (click)="handler()" is equivalent to element.addEventListener('click', handler). The binding automatically removes the listener when the component is destroyed. Without Angular’s binding (if you use native DOM events directly), you must remove listeners manually in ngOnDestroy to prevent memory leaks. Prefer Angular event bindings over manual addEventListener calls in component templates.(keydown.enter)="submit()" fires only when Enter is pressed, eliminating the need for if (event.key === 'Enter') submit() in the handler. Angular supports all key names from the KeyboardEvent.key property: (keydown.arrowUp), (keydown.control.s) (Ctrl+S), (keydown.shift.enter) (Shift+Enter). This makes keyboard shortcut implementation readable and declarative.$event object in Angular templates is typed as any in the template but should be properly typed in the handler method. Without proper typing, TypeScript cannot catch mistakes like accessing event.target.value on a MouseEvent (which has no value property on its target). Always type the event parameter in the handler: onInput(event: Event), onMouseMove(event: MouseEvent), onKeyDown(event: KeyboardEvent). Cast event.target as appropriate: const input = event.target as HTMLInputElement.Common Mistakes
Mistake 1 — Not preventing default on form submit (full page reload)
❌ Wrong — (submit)="onSearch()" without event.preventDefault(); the browser submits the form and reloads the page.
✅ Correct — always call event.preventDefault() in form submit handlers in Angular SPAs.
Mistake 2 — Using $event without casting target type (TypeScript errors)
❌ Wrong — onInput(event: InputEvent) { event.target.value }; TypeScript: Property ‘value’ does not exist on EventTarget.
✅ Correct — const input = event.target as HTMLInputElement; input.value.