Skip to content

Instantly share code, notes, and snippets.

@rafael-neri
Last active May 26, 2026 00:42
Show Gist options
  • Select an option

  • Save rafael-neri/d0e5a72718df5ce2cd64722fd28b1cff to your computer and use it in GitHub Desktop.

Select an option

Save rafael-neri/d0e5a72718df5ce2cd64722fd28b1cff to your computer and use it in GitHub Desktop.

Sprint 2: Integração com API e Fluxo Assíncrono

O Novo Problema Gerador

O sistema da sprint01 já permite cadastrar, listar e remover clientes com persistência local. Porém, os usuários precisam digitar o endereço manualmente — o que é lento e propenso a erros. Além disso, quando o sistema está "processando", não há nenhum feedback visual, deixando o usuário confuso.

O objetivo deste sprint é evoluir o sistema para consumir dados de uma API externa, implementar feedback visual de carregamento e orquestrar o fluxo de cadastro com operações assíncronas usando Promises e async/await.


Objetivos Técnicos

Nesta sprint, o grupo deve aplicar:

  • fetch() para requisições HTTP
  • async/await para fluxo linear
  • new Promise() para criar promessas customizadas
  • try/catch para tratamento de erros
  • Controle de estado da UI (desabilitar botão, feedback de carregamento)
  • Integração de dados da API ao LocalStorage

Requisitos da Interface

1. Novos campos no formulário

Adicionar ao formulário da sprint01:

  • CEP (obrigatório, texto)
  • Logradouro (preenchido automaticamente, readonly)
  • Bairro (preenchido automaticamente, readonly)
  • Cidade (preenchido automaticamente, readonly)
  • Estado / UF (preenchido automaticamente, readonly)

2. Integração com API ViaCEP

Ao sair do campo CEP (onblur ou oninput com 8 dígitos):

  • Fazer requisição para a URL da ViaCEP informando o CEP
  • Preencher automaticamente os campos de endereço com os dados retornados
  • Mostrar um texto "Carregando endereço..." enquanto a requisição não finaliza
  • Caso o CEP seja inválido (inexistente): exibir mensagem de erro no formulário
  • Usar async/await para a requisição e try/catch para capturar erros de rede

3. Feedback Visual durante o Salvamento

Ao clicar em "Salvar":

  • O botão deve ser desabilitado (disabled = true)
  • O texto do botão deve mudar para "Salvando..."
  • Após finalizar (sucesso ou erro), o botão deve voltar ao normal

4. Simulação de Processamento

Antes de salvar o cliente, o sistema deve passar por uma etapa de "validação" que simula um processamento assíncrono:

  • Criar uma Promise customizada que resolve após 2 segundos (usar setTimeout)
  • A promise deve resolver com sucesso sempre (não precisa de rejeição)
  • Acoplar esta promise no fluxo de salvamento usando await

Regras de Negócio

A. Fluxo de Cadastro Assíncrono

O evento de submit do formulário deve ser uma função async que executa em ordem:

  1. Validação local: Checar se os campos obrigatórios estão preenchidos (síncrono)
  2. Feedback visual: Desabilitar botão e mostrar "Salvando..."
  3. Promise customizada: Aguardar a promise de processamento (2 segundos)
  4. Salvar dados: Injetar no LocalStorage e no DOM
  5. Finalizar: Reabilitar o botão, limpar formulário

B. Estrutura do Cliente

Cada cliente deve conter: id (numérico), nome, email, plano, cep, logradouro, bairro, cidade, uf (string).

C. Tratamento de Erros

  • Se a API do ViaCEP falhar: exibir mensagem "Erro ao consultar CEP"
  • Se ocorrer qualquer outro erro no fluxo: mensagem genérica amigável
  • Usar try/catch para capturar todos os erros
  • O botão "Salvar" deve ser reabilitado em qualquer cenário (usar finally)

D. Persistência

  • Todos os dados do cliente (incluindo endereço) salvos na chave clientes_db no LocalStorage
  • Ao carregar a página, reconstruir os cards automaticamente
  • Botão "Remover" no card exclui do DOM e do LocalStorage

Diagrama do Fluxo de Cadastro

Usuário preenche formulário
          │
          ▼
  ┌───────────────────┐
  │ Validação local   │ ← síncrono
  │ (campos ok?)      │
  └───────┬───────────┘
          │ inválido
          ▼ (exibe erro)
          │ válido
          ▼
  ┌───────────────────┐
  │ Desabilitar botão │
  │ "Salvando..."     │ ← UI feedback
  └───────┬───────────┘
          │
          ▼
  ┌───────────────────┐
  │ simularProcessa-  │ ← await Promise
  │ mento()           │    (setTimeout 2s)
  └───────┬───────────┘
          │
          ▼
  ┌───────────────────┐
  │ Salvar no         │
  │ LocalStorage      │ ← clientes_db
  └───────┬───────────┘
          │
          ▼
  ┌───────────────────┐
  │ Atualizar DOM     │ ← renderizar cards
  │ Limpar formulário │
  │ Reabilitar botão  │ ← finally
  └───────────────────┘

Em caso de erro em qualquer etapa, o fluxo pula direto para o catch, que exibe a mensagem de erro, e o finally reabilita o botão.


Dicas Técnicas

  • Campos readonly podem ser estilizados com CSS (input:read-only)
  • Botão desabilitado pode ter opacidade reduzida (button:disabled)
  • Para limpar o CEP antes de buscar, remover caracteres não numéricos usando Expressão Regular
  • A URL da ViaCEP segue o padrão: https://viacep.com.br/ws/CEP_LIMPO/json/
  • Verificar se a resposta contém a propriedade erro para CEPs inválidos

Esboço da Promise customizada

A função que cria a Promise deve ter esta estrutura básica — o corpo (setTimeout e lógica de resolução) fica a cargo dos alunos:

function simularProcessamento() {
  return new Promise((resolve) => {
    // usar setTimeout para resolver após 2 segundos
  });
}

Esboço da função de buscar CEP

async function buscarEndereco(cep) {
  try {
    // limpar CEP (remover caracteres não numéricos)
    // se CEP não tiver 8 dígitos, sair da função
    // setar campos de endereço como "Carregando..."
    // fazer fetch para a URL da ViaCEP
    // se resposta não for ok, lançar erro
    // converter resposta para JSON
    // se JSON conter "erro", lançar erro
    // preencher campos (logradouro, bairro, localidade, uf)
  } catch (erro) {
    // exibir mensagem de erro
    // limpar campos de endereço
  }
}

Formato da resposta da API ViaCEP

A API retorna um JSON com esta estrutura. Use estes campos para preencher o formulário:

{
  "cep": "01001-000",
  "logradouro": "Praça da Sé",
  "bairro": "",
  "localidade": "São Paulo",
  "uf": "SP"
}

A resposta também pode conter "erro": true caso o CEP não exista.


Critérios de Avaliação

  • Uso correto de fetch para consumir ViaCEP
  • Uso de async/await no fluxo de cadastro
  • Criação de Promise customizada com new Promise
  • Uso de try/catch/finally para tratamento de erros
  • Botão desabilitado e com feedback textual durante salvamento
  • Integração correta do endereço ao LocalStorage
  • Interface atualizada dinamicamente (cards, limpeza de formulário)

Resultado Esperado

Ao cadastrar um cliente:

  1. Preencher CEP → endereço carregado automaticamente via API
  2. Clicar em "Salvar" → botão desabilita e mostra "Salvando..."
  3. Passa pela simulação de 2 segundos
  4. Cliente aparece na lista com endereço completo
  5. Recarregar a página → cliente continua salvo
  6. Remover → exclui do DOM e do LocalStorage

O sistema agora não é apenas um CRUD local — ele consome dados reais da internet, orquestra um fluxo assíncrono e dá feedback visual ao usuário durante o processamento.


Apresentação e Entrega do Projeto Final

A apresentação do projeto final acontecerá na última aula, no dia 27/05/2026. Cada grupo deverá demonstrar o funcionamento da aplicação e explicar brevemente as principais funcionalidades desenvolvidas.

O código-fonte do projeto deverá ser enviado por e-mail (rafepel@gmail.com) até 12h00 (meio-dia) do dia 27/05/2026.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment