Angular’s @Input and @Output decorators play a pivotal role in facilitating communication between parent and child components. In this blog post, we’ll delve into the practical usage of these decorators for effective data transfer and event handling.

1. Using @Input Decorator

The @Input decorator allows a parent component to pass data to a child component. Let’s explore a practical example:

Child Component:

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

@Component({
  selector: 'app-child',
  template: '<p>{{ childMessage }}</p>',
})
export class ChildComponent {
  @Input() childMessage: string = '';
}

Parent Component:

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

@Component({
  selector: 'app-parent',
  template: '<app-child [childMessage]="parentMessage"></app-child>',
})
export class ParentComponent {
  parentMessage = 'Message from Parent';
}

In this example, the ParentComponent passes the parentMessage data to the ChildComponent through the [childMessage] binding.

2. Using @Output Decorator

The @Output decorator allows a child component to emit events to its parent component. Let’s see how this works:

Child Component:

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

@Component({
  selector: 'app-child',
  template: '<button (click)="sendMessage()">Send Message</button>',
})
export class ChildComponent {
  @Output() messageEvent = new EventEmitter<string>();

  sendMessage(): void {
    this.messageEvent.emit('Message from Child');
  }
}

Parent Component:

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

@Component({
  selector: 'app-parent',
  template: '<app-child (messageEvent)="receiveMessage($event)"></app-child>',
})
export class ParentComponent {
  receivedMessage: string = '';

  receiveMessage(message: string): void {
    this.receivedMessage = message;
  }
}

Here, the ChildComponent emits a custom event with the message, and the ParentComponent listens for this event using (messageEvent)="receiveMessage($event)".

3. Combining @Input and @Output

Often, components need to both receive data from a parent and send events back.

Combining @Input and @Output provides a powerful way to achieve this dual communication:

Child Component:

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

@Component({
  selector: 'app-child',
  template: `
    <p>{{ childMessage }}</p>
    <button (click)="sendMessage()">Send Message</button>
  `,
})
export class ChildComponent {
  @Input() childMessage: string = '';
  @Output() messageEvent = new EventEmitter<string>();

  sendMessage(): void {
    this.messageEvent.emit('Message from Child');
  }
}

Parent Component:

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

@Component({
  selector: 'app-parent',
  template: `
    <app-child [childMessage]="parentMessage" (messageEvent)="receiveMessage($event)"></app-child>
    <p>Received Message in Parent: {{ receivedMessage }}</p>
  `,
})
export class ParentComponent {
  parentMessage = 'Message from Parent';
  receivedMessage: string = '';

  receiveMessage(message: string): void {
    this.receivedMessage = message;
  }
}

This example demonstrates the bidirectional communication between the parent and child components.

Conclusion

Leveraging @Input and @Output decorators is essential for building dynamic and interactive Angular applications. These decorators establish clear communication channels between parent and child components, enabling developers to create modular and reusable code. By mastering the use of these decorators, you can architect Angular applications that are both flexible and maintainable. Happy coding!

Similar Posts