# Tratando vazamento de memória em aplicações Angular.

Quando começamos o aprendizado de uma aplicação Angular, aprendemos o básico de RxJS para criar nossos componentes, principalmente quando temos que realizar alguma requisição HTTP. 
( [link](https://medium.com/tableless/entendendo-rxjs-observable-com-angular-6f607a9a6a00) )

O conceito de Observable implementado no RxJS é poderoso e nos permite acessar um fluxo de dados (como uma requisição Http) de uma maneira fluída e organizada.

Nesse exemplo eu estou fazendo uma requisição na API e me inscrevendo (subscribe) no retorno para atribuir a um objeto que usarei na minha interface.

%[https://gist.github.com/alvarocamillont/ed98552e15c0efb45fe31dfc6170507f]

Porém, nesse simples exemplo mora um perigo não muito claro, a ameaça silenciosa do vazamento de memória.

Quando esse componente não for mais utilizado, como por exemplo se o usuário ir para outra página, o Observable gerado por essa requisição HTTP ainda estará ativo pois o componente não se desinscreveu nele.

Como o componente já foi destruído, esse Observable ainda ativo virou um vazamento de memória(memory leak).

Isso causa uma degradação do desempenho, aumento do consumo de recursos da máquina e principalmente, perda de tempo do desenvolvedor, pois em uma aplicação grande esse tipo de erro é bem complicado de se localizar.

Então, o que podemos fazer ? Simples: garantir que meu componente se desinscreva sempre que ele não precisar mais do Observable!

OK, mas como fazer isso? Ah! Para isso temos algumas maneiras…

## A Básica.

Para se desinscrever de um Observable basta você seguir dois passos:

- Guardar a inscrição: O método subscribe tem como retorno um objeto do tipo subscription que representa a inscrição realizada.

- Chamar o método unsubscribe do objeto subscription.

%[https://gist.github.com/alvarocamillont/6b647b229a9ac1b10b172ee10dda1e8b]

Isso é simples, porém a questão é **quando **chamar o unsubscribe.

No Angular os componentes possuem métodos de ciclo de vida ( [Lifecycle Hooks](https://angular.io/guide/lifecycle-hooks) ), normalmente quando criamos via cli (ng g c) ele já vem de fábrica com o método OnInit.

%[https://gist.github.com/alvarocamillont/acb2b1af65b7d2590c7701fb32b54fba]

Para desinscrever o componente do Observable antes dele ser destruído, podemos então utilizar o método OnDestroy.

%[https://gist.github.com/alvarocamillont/d7f6cee0dd18349f661e50c6627c5185]

Pronto vazamento eliminado!

Porém nem sempre nossos componentes terão apenas um Observable,assim essa solução simples pode ficar um pouco feia …

Veja que adicionamos mais um Observable e tivemos que guardar mais uma Subscription e realizar mais uma condição no método onDestroy.

%[https://gist.github.com/alvarocamillont/b91817d12dc3f31140f59db5b2776a7c]

Podemos melhorar?

## O SubSink

Entra a biblioteca  [SubSink ](https://github.com/wardbell/subsink) focada em facilitar a coleta e a desinscrição nos Observables.

Ela é muito simples e tem apenas um método e um atributo:
    
- O atributo **sink **onde você adiciona a inscrição em uma lista que fica implícita.
    
- O método **unsubscribe **que realiza a desinscrição de toda a lista do atributo sink.

Vamos ao exemplo anterior verificar como fica mais simples a administração dos Observables do componente.

%[https://gist.github.com/alvarocamillont/acb506eda3d9dc188a966d94136dd58b]

Ainda temos mais uma alternativa. E essa já vem por padrão no Angular.

## O pipe async.

Quando componentes utilizam Observables em seus templates HTML uma alternativa muito interessante é o pipe async ( | async).

Com ele o componente apenas passa para o template o observable. E o motor de renderização do Angular faz o trabalho de realizar a inscrição (subscribe) e atribuir o retorno a um objeto.

A melhor parte é que o Angular cuida da desinscrição para você!

Vamos ver como ficam o template e o componente:

%[https://gist.github.com/alvarocamillont/16b243ce9fcda1c4a485162aef7bc095]

%[https://gist.github.com/alvarocamillont/78a92ebabea640f32773f1fd3ee08c3a]

Veja que não temos que chamar o OnDestroy, o framework faz isso para você!

Para mais informações, segue o vídeo da Loiane sobre o tema( [vídeo](https://www.youtube.com/watch?v=dKFeXl96nsA) ).

## Conclusão

Nesse artigo vimos os cuidados que temos que ter para evitar vazamento de memória (memory leaks) nas nossa aplicações Angular.

Resumindo:

  
-   Se seu componente utiliza observables para apresentar informações no template, utilize o pipe async.
   
-  Se você tem apenas um observable onde você precise fazer a inscrição(subscribe), guarde o objeto Subscription em uma variável e se desinscreva no método OnDestroy do componente.
   
- Caso seu componente tenha vários observables, utilize a bibiloteca SubSink para seu código ficar mais limpo.

Código fonte do exemplo( [link](https://github.com/alvarocamillont/example_sink) ).

Obrigado e compartilhe esse artigo com seus colegas para eles conhecerem esses cuidados na construção de componentes Angular.
