The End of @Input() & @Output(): Angular 20’s Game-Changing Update


For years, Angular developers have relied on @Input() and @Output() decorators for parent-child communication. While powerful, they often added boilerplate and confusion, especially in larger apps.

With Angular 20, things are changing dramatically. 🎉
The framework now embraces native Signals and introduces the model() API for cleaner, more reactive state flow.



🔴 Why Move Away from @Input & @Output?

  • Too much ceremony: separate properties for input/output.
  • Easy to create spaghetti state flow in big projects.
  • Not aligned with Angular’s new reactive primitives (Signals).



🟢 Angular 20: Inputs & Outputs with Signals

Instead of using decorators, Angular 20 provides functions for defining component bindings:

  • input() → replaces @Input()
  • output() → replaces @Output()
  • model() → combines input + output into a single two-way binding



📝 Code Examples

🟢 Old Way (Angular 19 with @Input and @Output)

// child.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  template: `
    

{{ title }}

` }) export class ChildComponent { @Input() title!: string; @Output() notifyParent = new EventEmitter(); notify() { this.notifyParent.emit('Hello from Child!'); } }
Enter fullscreen mode

Exit fullscreen mode

// parent.component.ts
@Component({
  selector: 'app-parent',
  template: `
    
    
  `
})
export class ParentComponent {
  parentTitle="Parent says Hi!";

  onNotify(msg: string) {
    console.log(msg);
  }
}

Enter fullscreen mode

Exit fullscreen mode

🔵 New Way (Angular 20 with Signals)

// child.component.ts
import { Component, input, output } from '@angular/core';

@Component({
  selector: 'app-child',
  template: `
    

{{ title() }}

` }) export class ChildComponent { title = input(); notify = output(); }
Enter fullscreen mode

Exit fullscreen mode

// parent.component.ts
@Component({
  selector: 'app-parent',
  template: `
    
    
  `
})
export class ParentComponent {
  parentTitle="Parent says Hi!";

  onNotify(msg: string) {
    console.log(msg);
  }
}

Enter fullscreen mode

Exit fullscreen mode

💡 Notice how much cleaner and signal-friendly this new API looks!

🟣Two-Way Binding with model()

The real game-changer is the model() API, which fuses input + output into a single signal.

// parent.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-parent',
  template: `
    

Parent Component

Parent Value: {{ parentTitle }}

` }) export class ParentComponent { parentTitle="Hello World"; }
Enter fullscreen mode

Exit fullscreen mode

💡 The model() API eliminates the need for separate @Input() and @Output(), giving us true two-way binding out of the box.



🌟 Why This Matters

  • 🚀 Less boilerplate, more readable code
  • 🔄 Seamless two-way binding with model()
  • ⚡ Reactive-first architecture, aligning with Angular Signals
  • 🧩 Better developer experience and performance



🏁 Conclusion

Angular 20 signals a major shift in how components talk to each other.
With input(), output(), and especially model(), we no longer need @Input() & @Output() decorators.

This isn’t just an API change—it’s a step toward a fully reactive Angular ecosystem.

👉 Stay tuned for more deep dives into Angular 20’s new features!



Source link

Leave a Reply

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