segunda-feira, 13 de julho de 2020

TypeScript #2: Melhorias no projeto EColeta

Pessoal, hoje vou comentar sobre o projeto que desenvolvi no post anterior sobre a criação de um marketplace de coleta de resíduos.No post anterior expliquei um pouco sobre a criação do backend desenvolvendo uma API (link) para ser consumida tanto Web como Mobile.
Neste post vou comentar sobre as novas funcionalidades desenvolvidas por mim dentro desse projeto, mostrando que com os conhecimentos obtidos da semana Next Level Week, foram desenvolvidas novas features:
  • Pesquisa de pontos de coleta (onde o usuário poderá pesquisar quais são os pontos disponíveis na sua cidade/cidade vizinha, e obter as informações sobre endereço do local);
  • Entrega de resíduos (onde o usuário poderá informar que entregou algum ítem de coleta em um determinado ponto de uma cidade).
A análise da feature de pesquisa foi:

O cliente informa o estado e cidade, e o sistema realiza uma pesquisa retornado todos os pontos localizados da localidade informada, atualizando o maps (LeafLeat), anexando o marcador nos pontos encontrados.
Logo abaixo, será retornado a imagem do ponto, junto com as suas informações do nome, email e telefone, para que o cliente consiga localizar/entrar em contato com o ponto que deseja entregar o ítem.

Para começar, eu comecei criando um arquivo .tsx (Nesse projeto foi usado TypeScrpit), onde será o index da Pesquisa do ponto de coleta. 

A primeira questão interessante que serviu como aprendizado nesse projeto foi que utilizamos a API do IBGE para nos retornarmos os estados e cidades do Brasil, assim evitamos possíveis inconsistências de informações como cidade/estado inexistente, e o cliente final ganha agilidade no processo de preenchimento do formulário, seja para pesquisa ou para cadastro.
Quando o cliente informa o estado é acionado o evento onChange, para obter o estado informado e pesquisar a cidade conforme o trecho de código abaixo:

<div className="field">
      <label htmlFor="uf">UF:</label>
        <select name="uf" id="uf" onChange={handleSelectUF}>
       <option value="0">Selecione uma UF</option>
           {ufs.map(uf=>(
             <option key={ufvalue={uf}>{uf}</option>
            ))}
         </select>
</div>

<div className="field">
        <label htmlFor="cidade">Cidade:</label>
          <select 
          name="cidade" 
          id="cidade" 
          value={selectedCity}
          onChange={handleSelectCidade}>
        <option value="0">Selecione uma Cidade</option>
               {cidades.map(cidade=>(
                   <option key={cidadevalue={cidade}>{cidade}</option>
                ))}
            </select>
           </div>
</div>
       <span>Foram localizados 
{quantidadeLocalizados < 1 ? '0' : quantidadeLocalizados} ponto(s)</span>                            
  <button type='submit'>Pesquisar</button>

E foi utilizado o useEffect para realizar as requisições para a API do IBGE, conforme o trecho de código abaixo:

    useEffect(()=>{
       axios.get<IBGEUFReponse[]>
('https://servicodados.ibge.gov.br/api/v1/localidades/estados')
       .then(response =>{
           const ufInitials = response.data.map(uf=> uf.sigla);
            setUFs(ufInitials);
           
       })
       
    }, [])
    //Carrega as cidades sempre que a UF mudar
    useEffect(()=>{
       if(selectedUF==='0'return;

       axios.get<IBGECidadeReponse[]>
(`https://servicodados.ibge.gov.br/api/v1/localidades/estados/
${selectedUF}/municipios`)
       .then(response =>{
           const cidades = response.data.map(cidade=> cidade.nome);
            setCidades(cidades);
           
       })

    }, [selectedUF]);

Após clicar no botão Pesquisar e for encontrado algum ponto com a localidade informada, o sistema populará o maps com a localidade (longitude,latitude) salvas no banco, usando o useEffect abaixo:
    
    useEffect(()=>{
        coordenadas.map(coordenada =>(
            setInitialPosition([coordenada.latitude, coordenada.longitude])
        ))
      
    }, [coordenadas])


Para mostrar as informações dos pontos localizados foi definida uma lista e dentro dela, será lido a lista de pontos, usando a função map, conforme o trecho de código abaixo:

<ul className='pontosLocalizados'>
        {pontos.map(ponto=> (
             <li key={ponto.id}>
              <img src={ponto.image} alt={ponto.name} 
className='pontosLocalizados'/>
             <br></br>

      <p className='pontosLocalizados'><b>{ponto.name}</b><br></br>
               {ponto.email}<br></br>
               {ponto.whatsapp}<br></br>
                                    
               </p>
              </li>
            ))}
</ul>


Desenvolvendo esses passos, consegui cumprir o que foi solicitado na análise comentada acima. Irei detalhar sobre a feature Entrega de resíduos no próximo post. Para mais detalhes do código, o repositório está disponível em:

Github: https://github.com/hiranneri/ecoleta-rocketseat
Linkedin: https://linkedin.com/in/hiranneri 

quarta-feira, 17 de junho de 2020

API Rest usando TypeScript

Olá pessoal, estou reativando o meu blog para falarmos sobre tecnologia e desenvolvimento, muitos assuntos foram obtidos durante esse tempo, e decidi que seria a melhor hora para voltar a falar sobre o que eu estudo/aprendo.

Neste post de retorno, gostaria de falar sobre Javascript, mas específico usando ele no back-end para criação de uma API REST.
Nesses meses e semanas de quarentena, decidi escolher uma stack de desenvolvimento para me aprofundar e desenvolver alguns projetos, venho estudado alguns tutoriais, vídeos aulas, e na primeira semana de junho, participei do evento gratuito da Rocketseat chamado: Next Level Week (NLW), que foi proposto um desafio de criar uma aplicação em uma semana, usando TypeScript, Knex e SQLite para a criação da API, e o sistema no Front-End e Mobile.

Neste projeto, o intuito inicial, foi a criação de um marketplace para coleta de resíduos, onde o usuário poderá cadastrar pontos de coleta e informar quais os tipos de resíduos que o ponto recebe.

Tendo ciência sobre o projeto, podemos iniciar com o gerenciador de pacotes:

NPM:

npm init            ou

YARN:

yarn init -y


Após o rodar o comando no terminal será criado o arquivo package.json
Recomendável realizar a instalação do TypeScript, podendo usar o comando:

yarn add -D typescript


Após a instalação do Typescript, podemos adicionar o Express (servidor)

yarn add express


Após as primeiras instalações, podemos estruturar as pastas do projeto, criando a pasta:

/src


Podemos criar o arquivo server.ts, como estamos trabalhando com TypeScript a extensão do arquivo é “.ts

Após a criação, iremos importar o Express:

import express from 'express';

const app = express();  -> Criação do app

app.use(express.json()); -> Esta linha serve para que o express entenda a

que as requisições em formato JSON.


Para utilizarmos as funções do Express, junto com o TypeScript, podemos instalar o pacote das tipagens, assim quando digitamos por exemplo “app.”, o VSCode (ou outra IDE de desenvolvimento), conseguirá identificar quais são as funções disponíveis do express().

Para instalar o pacote de tipagens usando:

NPM:

npm i @types/express            ou

YARN:

yarn add @types/express -D


Após instalar, já podemos ver a função listen, que escutará a porta “3333”, conforme código abaixo:

app.listen(3333); -> Execução do app na porta 3333

Após definido a porta de comunicação do servidor, já podemos criar as nossas rotas da aplicação

Rotas: Quando acessamos algum endereço por exemplo: localhost:3333/users, essa url seria uma rota, no exemplo abaixo a rota seria apenas "/", mais conhecido como rota raiz.


app.get('/', (request,response=> {

    
    /* Ação quando o usuário acessar a rota definida no primeiro 
    parâmetro, após o verbo HTTP GET. */
    
    return response.json( {message: "Olá Mundo"});
});

Caso precisamos que a API retorne todos os usuários, podemos fazer uma rota semelhante a essa:

Para atender a rota:  localhost:3333/users

app.get('/users', (request,response=> {
    
    /* Irei criar um objeto JSON apenas para exemplificar, 
    mas no cenário real, esse objeto seria retornado através 
    de uma pesquisa no banco. */
    
    return response.json( {
        'Gabriel',
        'Fernando',
        'José',
        'Joaquim'
    });
});

Caso precisamos que a API cadastre um usuário, podemos fazer uma rota semelhante a essa:

app.post('/users', (request,response=> {
    
    /* Quando acesso request.body, ele retornará os dados (corpo) 
    da requisição, que nesse caso seria o usuário informado 
    para ser cadastrado. */

    const {nomesobrenome,idadecidade= request.body; 

    /* Tendo esses dados em um objeto, podemos definir como salvar
    esses dados em algum banco e até realizarmos as validações, 
    após esse processo, podemos retornar o usuário salvo. */

    const usuarioCadastrado = {nome,sobrenome,idade,cidade};
    
    return response.json (usuarioCadastrado);
});

Existem mais conceitos que foram usados e que irei citar em novas publicações como o Knex e SQLite e etc., e também pretendo complementar esse projeto com novas funcionalidades. 
O código completo da API já está no meu github.

Sigam-me nas redes sociais: