Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
When building complex Angular applications, communication between components is essential.
Angular provides two powerful tools for exchanging data between components: Input and Output decorators.
In this blog post, I’ll walk you through how these decorators work and how to implement them in a real-world scenario.
We’ll also cover creating and handling events with the EventEmitter class.
Let’s dive into the details!
In Angular, components can communicate with each other using Input and Output decorators. These decorators make it easy to share data between a parent and child component.
Imagine you’re creating a dynamic form where a user’s input needs to update in real time.
You need a way to pass data between components and ensure that changes in one component reflect in others. The Input and Output decorators give you a clean, maintainable way to do that.
Let’s start by creating a simple Input component. This component will accept a value from its parent component and display it in the template.
Here’s how you can create a basic TestInputComponent that takes a string as input and displays it.
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-test-input',
template: `<h3>Input Value: {{ inputValue }}</h3>`,
})
export class TestInputComponent {
@Input() inputValue: string = '';
}
In this example:
inputValue
.Now, let’s add this component to the AppComponent template.
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-test-input [inputValue]="parentValue"></app-test-input>
`,
})
export class AppComponent {
parentValue: string = 'Hello from Parent Component!';
}
Here, the parentValue is passed from the parent component (AppComponent) to the child component (TestInputComponent) using the Input decorator.
What if we want the value to update dynamically? Let’s introduce a loop that updates the value over time.
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-test-input [inputValue]="dynamicValue"></app-test-input>
`,
})
export class AppComponent {
dynamicValue: string = 'Initial Value';
ngOnInit() {
let counter = 1;
setInterval(() => {
this.dynamicValue = `Value ${counter}`;
counter++;
}, 1000);
}
}
Here’s what’s happening:
Now that we’ve covered passing data into a component using Input, let’s explore how to emit events from a component using the Output decorator.
We’ll create a TestOutputComponent that contains a button. When the button is clicked, the component will emit an event to the parent component.
First, define the child component with an Output event emitter.
import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-test-output',
template: `<button (click)="emitEvent()">Click Me!</button>`,
})
export class TestOutputComponent {
@Output() myEvent = new EventEmitter<string>();
emitEvent() {
this.myEvent.emit('Event Emitted!');
}
}
In this code:
myEvent
.'Event Emitted!'
) when the button is clicked.Now, we’ll handle the emitted event in the parent component.
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-test-output (myEvent)="handleEvent($event)"></app-test-output>
`,
})
export class AppComponent {
handleEvent(eventData: string) {
console.log('Received Event:', eventData);
}
}
'Event Emitted!'
) is logged in the console.To see this in action:
Here’s the full code for both components:
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-test-input',
template: `<h3>Input Value: {{ inputValue }}</h3>`,
})
export class TestInputComponent {
@Input() inputValue: string = '';
}
import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-test-output',
template: `<button (click)="emitEvent()">Click Me!</button>`,
})
export class TestOutputComponent {
@Output() myEvent = new EventEmitter<string>();
emitEvent() {
this.myEvent.emit('Event Emitted!');
}
}
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-test-input [inputValue]="dynamicValue"></app-test-input>
<app-test-output (myEvent)="handleEvent($event)"></app-test-output>
`,
})
export class AppComponent {
dynamicValue: string = 'Initial Value';
ngOnInit() {
let counter = 1;
setInterval(() => {
this.dynamicValue = `Value ${counter}`;
counter++;
}, 1000);
}
handleEvent(eventData: string) {
console.log('Received Event:', eventData);
}
}
Using Input and Output decorators in Angular helps you manage data flow between components, making your application easier to scale and maintain.
You can pass values into a component with Input, and emit events using Output with EventEmitter. This communication mechanism is key to building modular, reusable components in Angular.
Feel free to experiment with this setup by passing different data types, handling multiple events, or even chaining outputs from different components. Happy coding!