@Output(), compartilhando dados entre filho e pai, e até avô !
Tags: angular, typescript, braziliandevs, tutorial
Published: 2021-08-10 13:31:02

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j7ykj0phjo8nlu00zb22.jpg)

Imagine o cenário acima, que na qual por algum motivo precisamos avisar o componente modal(Pai) que houve um click no botão(Filho), para que assim o componente pai através de um método que só ele tem contabilize o total de clicks em seu componente filho. 

Então, se formos pensar em algumas possibilidades para utilizar o método que contabiliza o total de click poderíamos talvez criar uma service e remover o método do componente pai, e se você for bem "malaco" talvez possa pensar na idéia de importar o componente-pai.component.ts dentro do componente-filho.componente.ts, o que como meu líder Vitor Hugo, o "Vitão" disse, é extremamente e simplesmente proibido importar componente.ts ! haha

Então, voilà, temos a maravilhosa propriedade @Output()

## Propriedade @Output()

Quando utilizamos o @Output() marcamos uma propriedade que permite o fluxo de dados do componente filho para o componente pai. Essa propriedade gera um evento que notifica para o componente pai que algo aconteceu no componente filho, e para emitirmos esse evento para o componente pai, utilizamos o EventEmiter do @angular/core. 

## How to do ... 

Primeiro, precisamos importar o Output e nosso EventEmitter na classe do nosso componente: 

```typescript
import { Output, EventEmitter } from '@angular/core';
```

Depois, precisamos declarar nossa @Output(), que será como "a nossa fala" para nosso componente pai:

```typescript
@Output() houveUmClick = new EventEmitter<void>();

constructor() {}
```

Nosso new EventEmitter<void>, diz que o angular tem que criar um emissor de eventos do tipo void, mas, podemos passar string, objetos e tudo mais. Porém, em nosso exemplo precisamos só emitir que ocorreu um click, então podemos passar como void !

Depois de criado, precisamos pensar quando queremos informar para nosso componente pai que houve um click, como por exemplo no cenário abaixo: 

- Quando um método retornar sucesso ou simplesmente quando for iniciado, então, declaramos:

```typescript
ngOnInit(): void {
 
   this.houveUmClick.emit();
}
```

Na linha de código, queremos dizer o seguinte: 

- Angular, quando você iniciar o componente, fala para o componente pai que se estiver me ouvindo que houve um click e que ele resolve o que fazer, e fazemos isso através do .emit(); 

Caso o nosso componente pai esteja esperando alguma string ou alguma outra coisa, teríamos que ter criado um EventEmitter<tipoEsperado>(); e quando fossemos emitir que houve uma ação, em nosso emit() passaríamos o que nosso componente pai esta esperando. No caso do exemplo, só precisamos alertar que houve um evento com o componente filho então podemos passar vazio.

E após isso, esta feito, nosso componente filho ja esta falando houve um evento com ele, agora nosso componente pai precisa passar a nos ouvir.

## Como ouvir nosso componente filho ...

Após termos criado nossa @Output() em nosso componente filho o componente pai precisa passar a ouvir-lo, então fazemos isso da seguinte forma:

Quando declaramos nosso componente filho em nosso html, precisamos passar nele também o @Output() que criamos nele, que é a forma como ele irá falar com o componente pai, da seguinte forma:

```html
<div class="main-content">
   <app-component-button (houveUmClick)="adicionaMaisUmCickContabilizado()"></app-component-button>
</div>
```

Então, o houveUmClick é o nome da "forma" que nosso filho irá falar com a gente, e após ele falar, eu pego e chamo o método do componente pai que é adicionaMaisUmCickContabilizado() e nele eu faço o que é preciso. 

Vale lembrar que podemos passar mais de um emissor e para mais de um componente filho. Agora, uma pergunta super válida: 

- E se eu precisar que o componente "vô" do meu componente pai saiba que houve um click? Se eu precisasse subir um nível ainda na hierarquia ? 

A resposta é simples, assim como criamos uma @Output() em nosso filho para que ele consiga falar, teríamos que criar uma @Output() em nosso componente pai, para que assim ele consiga conversar com o componente pai dele e o componente "vô" passaria a escuta-lo e fazer o que precisa ser feito :D

Obrigado pela leitura e até a próxima ! :D :D