@Input @Output decorators in Angular
Tags: angular, typescript, javascript
Published: 2019-07-18 18:10:48

##Decorator
A decorator is simply a function that modifies definition of a class or properties inside a class. These decorators are also called as annotations and are mainly classified as two types - _class decorator_, and _class field decorator_.

##Class Decorator
A decorator that appears immediately before a class definition. 
For instance, `@Component()` decorator which is mentioned right before a class definition, has metadata that helps Angular to know how those classes or properties should work.

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

Some other examples of class decorators are `@Injectable()`, `@NgModule()`, `@Directive()`, `@Pipe()`

##Class Field Decorator
A decorator that appears immediately before a field in a class definition.
For instance, `@Input()` and `@Output()`.
```
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  @Input() count;
  // code
}
```
To understand the `@Input()`, `@Output()` decorators in detail, I took a simple Parent-Child relationship as an example. Let's say we have a Parent who gives chocolates to their Child and Child after receiving the chocolates thanks their Parent.

![Input Output Decorators](https://cdn-images-1.medium.com/max/1600/1*tUL26MF1SXGQnRjNLSSgQA.gif)
<figcaption>Parent to Child & Child to Parent Components Communication</figcaption>
From the above GIF, Maroon colored block indicates the ParentComponent, the blue colored block indicating the `ChildComponent`.

##Parent to Child Communication, use @Input( )
Setting the chocolate count to 0 at first. When user clicks on the Send Chocolates button on the UI, the chocolate count increases.

_parent.component.html_
```
<button (click)="sendToChild()">Send Chocolates to Child</button>
<app-child [chocolateCount]="chocolate"></app-child>
parent.component.ts
export class ParentComponent { 
  chocolate = 0;  
  sendToChild() { 
    this.chocolate++; 
  }
}
```
When Parent sends chocolates to Child, Child should be able to receive it. Hence, we will catch hold of chocolates using chocolatesCount variable and decorate it with @Input() decorator as it is coming from the ParentComponent.

_child.component.html_
```
<p>Chocolates recieved from Parent - {{chocolateCount}}</p>
child.component.ts
export class ChildComponent {
  @Input() chocolateCount;
}
```

##Child to Parent Communication, use @Output( )
Now that Child received chocolates from Parent, the Child should thank Parent.

_child.component.html_
```
<button (click)='sayThanks($event)'>Say 'Thank you' to Parent</button>
```
Using `@Output()`is little tricky but is easy when you understand it right. Let's decorate the thanks variable with `@Output()`. Using thanks variable, we will emit the value ('Thank you') to the Parent Component from Child Component. Also, we would need an `EventEmitter` instance where we specify the type of value we are emitting.

_child.component.ts_
```
export class ChildComponent {
@Output() thanks: EventEmitter<string> = new EventEmitter<string>();
  
sayThanks($event) { 
    this.thanks.emit('Thank you'); 
  }
}
```
Now listen to this event in the ParentComponent. The event parameter will give you 'Thank you' text which came from the ChildComponent.

_parent.component.html_
```
<app-child [chocolateCount]="chocolate" (thanks)="sayThanks($event)"></app-child>
```
_parent.component.ts_
```
export class ParentComponent {
  chocolate = 0; 
  thankYouText = '';
  sendToChild() { 
    this.chocolate++; 
  }
  sayThanks(event) { 
    this.thankYouText = event; 
  }
}
```
With this, you saw Parent to Child & Child to Parent Components Communication using `@Input()` and `@Output()` decorators in Angular. Hope you enjoyed reading this post. You may refer to the full code [here](https://github.com/chilupa/angular-input-output-decorators).