🚀 Angular’s model() – A Cleaner Way to Do Two-Way Binding

Angular has always had great tools for building interactive, scalable apps — and if you’ve been working with it for a while, you’re probably no stranger to the classic banana-in-a-box syntax: [(value)]. 🍌

But in 2025, Angular is leveling up again — introducing the new model() function, making two-way binding simpler and more declarative than ever. No more wiring up @Input() and @Output() manually. This is Angular’s move toward cleaner, less repetitive code.


🔄 The Old Way: @Input() + @Output()

Traditionally, to set up two-way binding between a parent and child component:

@Input() value: number;
@Output() valueChange = new EventEmitter<number>();

This works — but when you’re doing it across multiple components, it gets repetitive quickly. That’s where model() comes in.


✅ The New Way: model()

Angular’s new model() function replaces both @Input() and @Output() in one line. It works seamlessly with the existing [( )] syntax and keeps your component logic much cleaner.


🧮 Example: A Counter with model()

Child Component (CounterComponent):

import { Component, model } from '@angular/core';

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

increase() {
this.count.set(this.count() + 1);
}

decrease() {
this.count.set(this.count() - 1);
}
}

Parent Component:

import { Component, signal } from '@angular/core';
import { CounterComponent } from './counter.component';

@Component({
selector: 'app-root',
standalone: true,
imports: [CounterComponent],
template: `
<h3>Current count: {{ currentCount() }}</h3>
<app-counter [(count)]="currentCount" />
<button (click)="currentCount.set(0)">Reset</button>
`,
})
export class App {
currentCount = signal(0);
}

🛠 Why model() Is a Win

  • No More Boilerplate – Say goodbye to @Input() and @Output() duplication.
  • Cleaner Templates – Keeps bindings intuitive and inline with the rest of your code.
  • Fully Reactive – Works directly with Angular Signals and supports updates in both directions.

💡 Why This Matters

Angular is moving fast, and new features like model() help you keep your components lean and maintainable — especially in larger apps. It simplifies reactive communication between components without giving up control or readability.


🧠 Final Thoughts

model() isn’t just syntactic sugar — it’s a clear step toward a more modern Angular. If you’re still wiring up inputs and outputs manually, it’s time to try this cleaner approach. It works great in simple examples like counters, but scales beautifully for complex UIs too.

So the next time you go to reach for that banana-in-a-box, try using model() instead — and see how much cleaner your code becomes. ✨

Let me know if you’d like to refactor any of your existing components using model() — I’ll help walk you through it!

Leave a Comment

Your email address will not be published. Required fields are marked *