Angular: Estendendo o HttpClient e criando Interceptors dinâmicos
O dia que eu descobri que às vezes a gente precisa ir longe demais
Era uma sexta-feira, eu tinha acabado minha tarefa e parei pra consertar um tal "loader" que bloqueava a tela ao digitar nos campos de autocomplete. Esse loader era um interceptor exibido a cada Request.
Se tratando de uma arquitetura recém construída, seria simples resolver o problema: Remove o loader de lá e faz o componente controlar o coitado, já que cada componente sabe de suas necessidades. OOOOUUU, encapsula o HttpClient em uma classe sua e adicione as suas próprias mágicas dentro dela.
Porém, pela proporção "páginas que precisariam ser completamente refatoradas" versus "oculta o loader desse campinho aqui", a solução mais rápida foi desabilitar o loader somente nos campos de autocomplete, pois todos nós temos um prazo. Nosso projeto também.
P.S.: Apesar do motivo, essa solução pode se aplicar a adicionar/remover caminhos de API, controlar o cache ou se o token de autenticação deve ser utilizado ou não.
A primeira alternativa
A primeira alternativa foi a mais simples porém a menos elaborada: adiciona um param "hideLoader" e usa ele pra dizer se o loader pode ser exibido ou não. Porém, procurando nas issues do Angular, já existia uma pra isso (#18155), e a galera não curtiu muito essa ideia por conta de enviar os dados pro servidor.
Pesquisando um pouco mais, cheguei à solução do ngx-rocket, que estendeu o HttpClient em uma nova classe e passou a responder no lugar dele adicionando seus próprios métodos. Não sei se o que me atraiu foi a criatividade, a complexidade, ou o fato de eu poder mapear todos os lugares que usam os métodos customizados sem muito esforço (vai que a feature é incluída no Angular 7 e eu tenho que refatorar tudo), mas é dessa solução que a gente vai falar aqui.
Estendendo o módulo
O Typescript tem um recurso bem interessante em que é possível estender um módulo. No nosso caso, vamos estender o módulo e exportar a interface HttpClient já com os métodos customizados. Para isso, vamos criar o arquivo http.service.ts com o seguinte conteúdo:
Customizando Interceptors
Aqui, vamos encadear a chamada dos interceptors e permitir a customização deles:
O HttpClient, digo… o nosso Service
Ainda no nosso HttpService, vamos criar a classe que dá nome a ele. O método hideLoader é o responsável por desabilitar o interceptor de loader. Já o request, sobrescreve o método original para utilizar os interceptors definidos no nosso array.
Registrando o Service
Vamos registrar o HttpService substituindo o HttpClient para que o mesmo seja injetado em todos os lugares que o HttpClient já é utilizado. No meu caso, eu registrei direto no app.module.ts:
Utilizando
Por último, vamos utilizar o nosso método nos providers que chamam as URLs de autocomplete.
Com isso, nós podemos utilizar métodos customizados no HttpClient e manter o resto da nossa aplicação funcionando, e também podemos rastrear onde eles foram utilizados caso ocorra alguma mudança na ferramenta.
E aí, curtiu? Tem alguma dúvida? Se tiver qualquer coisa que eu possa fazer pra tornar esse artigo melhor, se quiser reclamar, elogiar ou sugerir outro artigo, manda ver nos comentários ou no twitter. Feedbacks são sempre super bem vindos.