The Power of Angular @Input and @Output Decorators: A Comprehensive Overview
Tags: typescript, angular, beginners, programming
Published: 2023-06-11 02:23:49

Are you working on a codebase in which you use a component you created but need to display data or perform a click function in your child component from the parent component? or perhaps you learned about reusable components and wanted to test them out, but your child or reusable component is having issues talking and communicating with other components? Cheers and congratulations; the purpose of this article is to help you not only comprehend but also solve the problem of communication between components in Angular using Angular's @input and @output decorators.

## What is the `@input` and `@output` Decorator?


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p2l0n7f43qd7eeq7yitj.png)



So, first and foremost, let's talk about decorators. Decorators are a way of adding metadata to a class, its properties, or its methods in the context of Angular. Decorators are basically functions that wrap around a class, property, or method and change its behavior in some way.

However, let us briefly discuss class decorators and class field decorators. Class decorators are used to decorate classes, whereas class field decorators are used to decorate class fields or properties.

Class decorators modify the behavior of the entire class. By way of illustration, the `@Component()` decorator, which is mentioned immediately before a class definition, contains metadata that aids Angular in understanding how the classes or properties should function.

```ts
@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
})
export class AppComponent {
 title = 'app';
}
```

Whereas class field decorators modify the behavior of a specific property or field within a class. The best examples are the `@Input` and `@Output` decorators.

Now that we've covered that, let's look at the `@Input` and `@Output` decorators in particular. These are two of the most common Angular decorators.

## `@Input` Decorator - Parent-to-Child communication

The `@Input` decorator is used to pass data from one component to another. When the `@Input` decorator is applied to a property in a child component, it transforms it into a property that can receive data from its parent component. This enables the parent component to communicate with the child component and pass data to it, which can then be used in the template or logic file of the child component.

To have a practical understanding of the above theory, take for example you have two components:

1. Parent Component
    
2. Child Component
    

The parent component is trying to teach its child how to count numbers, it does this by asking its child to render the number of times a button in its component was clicked. How would this be achieved? Let's take a look at how the parent component `HTML` would look like below:

### parent-component.html file

```html
<button (click)="teachChildNumbersCounting()">Ask Child</button>
<app-child [clickCounts]="clicks"></app-child>
```

The child component is given the value of clicks in the code above. The child component keeps track of changes in the `clickCounts` value and updates the child component's count value accordingly. Using interpolation from the child.component.html file, the child component will then show the value of the count in the template.

Wondering what the logic file for the parent component would look like? You can examine the following lines of code below:

### parent-component.ts file

```typescript
export class Component1 { 
  clicks = 0;  
  teachChildNumbersCounting() { 
    this.clicks++; 
  }
}
```

In the above lines of code, the property `clicks` is defined and a value of 0 is set to it. Following it is a definition of the `teachChildNumbersCounting()` function used in `parent-component.html`, the file that adds +1 to the clicks' value whenever the function is triggered by clicks from the button and then passed to the child component.

However, the child component's `clickCounts` property is decorated with the `@Input` decorator in the `child-component.ts` file so that the child component can render the clicks property through it. The majority of the work is completed here. As was already said, the `@Input` decorator turns the property `clickCounts` into a data-receiving property for its parent component. This allows communication between the parent and child components, all thanks to the `@Input` decorator.

The code implementation for the above explanation on how the `@Input` decorator is used in the `child-component.ts` file can be examined in the lines of code below:

### child-component.ts file

```typescript
@Component({
....
}}
export class childComponent {
  @Input() clickCounts: number;
}
```

With the above implementation, the child component can now render the number of times the parent component clicked the button in its `component.html` file by making use of interpolation for data binding to display the value set to the `clickCounts` property.

However, you can examine the code implementation for the explanation made below:

### child-component.html file

```xml
 <div>
     <p>No of clicks from parent's Component - {{clickCounts}}</p>
</div>
```

## @Output Decorator - Child-to-Parent communication

The `@Output` decorator, on the other hand, is used to emit events from a child component to a parent component. When the `@Output` decorator is applied to a property or method in a child component, it transforms it into an event emitter that can be triggered to emit data or events from the child component to its parent component. This enables the child component to communicate with and send data or events back to the parent component.

Nevertheless, keep in mind the example from the section above. Since the child component can now display how many times the button in the parent component was clicked on. Now consider our example in reverse, where the parent component displays the number of times the button in its child component was clicked.

To achieve this, some edits would be made to the child component. First, you can take a look at the child's template component in the following lines of code below:

### child-component.html file

```xml
  <div>
     <p>No of clicks from parent's Component - {{clickCounts}}</p>
     <button (click)='countClicks()'>Click to count from child</button>
  </div>
```

The logic file for the above template can be examined below:

### child-component.ts file

```typescript
export class Component2 {
@Output() childToPrentCountClick: EventEmitter<number> = new EventEmitter<number>();
@Input() clickCounts: number;
countClicks() { 
  this.childToPrentCountClick.emit();
  }
}
```

The event emitter in the component mentioned above is `childToPrentCount`. This listens to when a click event is triggered. For this to be effective, the parent component would need to be updated. This can be observed in the following lines of code:

### parent-component.html file

```xml
<button (click)="teachChildNumbersCounting()">Ask Child</button>
<p>No of clicks from child's Component - {{clicks}}</p>
<app-child 
[clickCounts]="clicks" 
childToPrentCountClick="teachChildNumbersCounting()" 
></app-child>
```

In the above lines of code, the function `teachChildNumbersCounting()` was passed to the `childToParentCountClick` event emitter that is decorated with the `@Output` decorator in the child's decorator. This allows our button clickable with desired logic controlled by the parent component without the child component performing any logic on the button click.

## Conclusion

To summarize, during this article, we have discussed how the `@Input` decorator passes data from a parent component to a child component, whereas the `@Output` decorator emits events from a child component to a parent component. These decorators, when used together, enable powerful communication and interaction between components in Angular applications.