Filtrando no NodeJs
Tags: node, javascript, postgres
Published: 2020-06-02 01:52:58

Olá, meu nome é Bruno Padilha, sou desenvolvedor de software e esta é minha primeira publicação na área de programação. 

Me deparei com um problema no meu trabalho que era filtrar um ou mais dados na database de acordo com o que é passado no req.query.Tentei procurar diversas fontes onde poderiam me ajudar na época com isso, entretanto, não encontrei nada. Como acabei conseguindo resolver depois de um tempo e agora estou aqui criando esse artigo para te ajudar se está passando por este mesmo problema.
Vamos lá?

Usarei aqui as tecnologias como banco de dados o postgres com ORM sequelize e a linguagem javascript.

Na imagem 1 é possível ver a tabela users no banco de dados Postgres:

![imagem 1 - tabela users](https://dev-to-uploads.s3.amazonaws.com/i/9vihr8voqbvgb3fsf6xl.png)
imagem 1 - tabela users

Se eu simplesmente quiser passar um req.query dentro do findAll de User mostrado no código abaixo, vai “funcionar” como mostrado nas imagens 2 e 3.

```javascript

import User from '../models/User';
 
class UserController {
 async filter(req, res) {
   const data = await User.findAll({
     where: req.query,
   });
   return res.status(200).json(data);
 }
```

![imagem 2 - resultados com cabelo vermelho
](https://dev-to-uploads.s3.amazonaws.com/i/8h1r2tx9bnsbd9g43vvy.png)
imagem 2 - resultados com cabelo vermelho

![imagem 3 - resultados para genero feminino
](https://dev-to-uploads.s3.amazonaws.com/i/r79zdfj1cjzs7nwbk6pj.png)
imagem 3 - resultados para genero feminino

Até mesmo se eu não passar nenhum dado no req.query, todos os resultados no banco de dados serão exibidos, como mostrado na imagem 4.

![imagem 4 - resultados sem passar nenhum parâmetro no filtro
](https://dev-to-uploads.s3.amazonaws.com/i/sec4vv472gcr0pgq7liq.png)
imagem 4 - resultados sem passar nenhum parâmetro no filtro

Entretanto, se o frontend cometer algum erro de tentar pesquisar por uma coluna que não existe na tabela do banco de dados, ou alguém interceptar essa request para o backend e tentar procurar por algum parâmetro diferente, isso o banco de dados, dizendo que não existe na tabela o campo buscado, como mostrado nas figuras 5 e 6.

![imagem 5 - erro no DB quando se passa parâmetros errados
](https://dev-to-uploads.s3.amazonaws.com/i/c1ws2wlo4uvku35jwkol.png)
imagem 5 - erro no DB quando se passa parâmetros errados

![imagem 6 - erro no DB quando se passa os parâmetros errados
](https://dev-to-uploads.s3.amazonaws.com/i/npclsrav4i4e0lk97unt.png)
imagem 6 - erro no DB quando se passa os parâmetros errados

Com isso, precisamos desestruturar o req.query, criar uma constante where, que é onde você vai procurar dentro do findAll e validar que esses dados estão passando, pois, em um filtro, temos a opção de procurar ou não esses dados, correto? O código ficará  assim:

```javascript

async filter(req, res) {
   const { id, name, hair_color, gender } = req.query;
   const where = {};
   if (id) where.id = id;
   if (name) where.name = name;
   if (gender) where.gender = gender;
   if (hair_color) where.hair_color = hair_color;
 
   const data = await User.findAll({
     where,
   });
   return res.status(200).json(data);
 }
```
Como pode ser notado, eu criei um objeto where onde caso o parâmetro que foi passado no req.query exista, ele vai sendo incluído no objeto where. Para assim o mesmo ser pesquisado dentro do ORM.

Na imagem 7 trás os resultados mesmo passando uma coluna que não existe como req.query.

![imagem 7 - retornando resultado mesmo que passe um req.query de uma coluna que não existe](https://dev-to-uploads.s3.amazonaws.com/i/vjkh8blmzu67q7kl99oo.png)
imagem 7 - retornando resultado mesmo que passe um req.query de uma coluna que não existe


## EXTRA

Também podemos fazer algo parecido com um include. Mostrarei agora na imagem 8 a tabela de groups que, como vimos na imagem 1, o id_group está linkando as duas.

![imagem 8 - tabela groups no banco de dados](https://dev-to-uploads.s3.amazonaws.com/i/ctliy3y4dz6pd2is8nxz.png)
imagem 8 - tabela groups no banco de dados


```javascript
import User from '../models/User';
import Group from '../models/Group';
 
class UserController {
 async filter(req, res) {
   const { id, name, hair_color, gender, group } = req.query;
   const where = {};
   if (id) where.id = id;
   if (name) where.name = name;
   if (gender) where.gender = gender;
   if (hair_color) where.hair_color = hair_color;
 
   const data = await User.findAll({
     where,
     include: { model: Group, where: group ? { group } : {} },
   });
   return res.status(200).json(data);
 }

```
E seguem diferentes resultados nas imagens 9, 10, 11 e 12. Nota-se que na imagem 11 não vai resultar em nenhum dado, pois não existe alguém de cabelo preto no group Teste3.

![imagem 9 - resultado mostrando o filtro com group Teste3
](https://dev-to-uploads.s3.amazonaws.com/i/frvtfvzvmpknir70ocja.png)
imagem 9 - resultado mostrando o filtro com group Teste3

![imagem 10 - resultado mostrando o filtro com group Teste2
](https://dev-to-uploads.s3.amazonaws.com/i/87e8n3865m8215kisb1e.png)
imagem 10 - resultado mostrando o filtro com group Teste2

![imagem 11 - não retornando nenhum resultado mostrando o filtro com group Teste 3 e cabelo de cor black.
](https://dev-to-uploads.s3.amazonaws.com/i/a18mgvjrqxni0k00a9qp.png)
imagem 11 - não retornando nenhum resultado mostrando o filtro com group Teste 3 e cabelo de cor black.

![imagem 12 - retornando a combinação de resultados de roup Teste2 com cabelo de cor black.
](https://dev-to-uploads.s3.amazonaws.com/i/4xgzofkn334z93xzu57j.png)
imagem 12 - retornando a combinação de resultados de roup Teste2 com cabelo de cor black.

Muito obrigado por ler até aqui, espero que goste e estou totalmente aberto a críticas e melhorias no código. Espero ter ajudado.