Um programador sénior não escreve código aleatoriamente. Ele planeia.
Vamos construir a lógica mental deste projeto, do zero ao fim. Se conseguires responder a tudo, estás pronto para programar qualquer coisa!
1. Fase de Planeamento: O que precisamos antes de sequer abrir o VS Code?
Ir ao Google copiar um projeto de meteorologia feito.
Identificar as funcionalidades essenciais (Requisitos) e desenhar um esboço da interface (Wireframe).
Começar logo a escrever funções aleatórias.
2. Estrutura (HTML): Como organizarias o layout desta app?
Tudo dentro de uma única `div`, misturado.
Uma secção para a "Sidebar" (pesquisa) e outra para o "Conteúdo Principal" (dados do tempo), ambas dentro de um contentor pai.
Usar uma tabela HTML gigante para alinhar tudo.
3. Seleção (JS): O HTML está pronto. Qual é o primeiro passo no JavaScript?
Adicionar animações CSS.
Começar a fazer pedidos à API.
Criar variáveis que guardam referências para os elementos do ecrã (Inputs, Botões, Texto de Saída) usando `document.querySelector`.
4. Interação: Queremos que algo aconteça quando o utilizador carrega "Enter" no input. O que usamos?
Um loop `while` que verifica a toda a hora se alguém escreveu.
Um `addEventListener` para escutar o evento 'keypress' ou 'submit'.
A propriedade HTML `onclick`.
5. API: Agora precisamos dos dados da cidade. A chamada à API é instantânea?
Não. Devemos usar `async/await` para esperar pela resposta sem bloquear o site (promessas).
Sim, é imediato, funciona como uma variável normal.
Não sei, uso `setTimeout` de 5 segundos para garantir.
6. UX: Enquanto o `await` espera pelos dados, o que deve ver o utilizador?
Um ecrã branco.
O site congelado e inamovível.
Um indicador visual de "Carregando..." (Loader/Spinner) para dar feedback imediato.
7. Robustez: E se o utilizador escrever "Cidade Imaginária"?
O site deve crashar e mostrar erros na consola.
Devemos usar um bloco `try...catch` para apanhar o erro e mostrar um alerta amigável: "Cidade não encontrada".
Ignoramos e mostramos dados de Lisboa por defeito.
8. Organização: O código está a ficar grande. Como organizamos a lógica da App?
Deixamos tudo numa "tripa" de 500 linhas.
Usamos Classes (POO) ou Módulos para agrupar funções relacionadas (ex: uma Classe `WeatherApp` que gere o estado).
Escrevemos o JS dentro das tags HTML.
9. Fluxo de Dados: A API do tempo pede Lat/Lon, mas o utilizador escreve "Lisboa". Como resolvemos?
O JavaScript adivinha as coordenadas.
Obrigamos o utilizador a saber a latitude de Lisboa.
Encadeamento de APIs: Primeiro chamamos uma API de "Geocoding" (Nome -> Lat/Lon) e passamos esse resultado para a API de Meteorologia.
11. Estilo Inteligente: Porquê usar Variáveis CSS (`:root`) em vez de cores fixas `hex`?
Porque o navegador processa mais rápido.
Para facilitar a manutenção: se quisermos mudar o tema para "Dark Mode" ou outra cor, mudamos num só sítio e aplica-se a tudo.
Não serve para nada.
12. Layout: Grid vs Flexbox. Qual usar para a estrutura principal (Sidebar + Conteúdo)?
CSS Grid é ideal para estruturas layouts bidimensionais (colunas e linhas) como o esqueleto da app.
Flexbox, porque funciona melhor com tabelas.
Float left e clear fix, com antigamente.
13. Validação: O que fazer se o utilizador escrever apenas espaços " " no input?
Enviar os espaços para a API e esperar que funcione.
Usar `.trim()` para remover espaços extra e verificar se a string está vazia antes de fazer qualquer pedido.
Gritar com o utilizador.
14. Strings Modernas: Como inserimos a variável `cidade` dentro do URL da API?
Concatenar com muitos "+" (ex: url + kota + ".com").
Usar Template Literals com backticks (`) e `${cidade}` para uma leitura limpa.
Escrever o URL à mão sempre.
15. A Internet Falha: O `fetch` pode completar-se mas a API devolver erro (ex: 404). Como detetamos?
O `catch` apanha automaticamente erros 404.
Temos de verificar `response.ok` (se é true). Se não for, lançamos um erro manual `throw new Error()`.
Ignoramos e mostramos "undefined".
16. Dados: O `fetch` devolve um "Stream". Como obtemos o Objeto JavaScript real?
Usamos `JSON.parse()`.
Precisamos de um segundo `await response.json()` para ler o corpo da resposta e transformá-lo em objeto.
Lemos como texto simples.
17. Apresentação: A API devolve 22.4124°C. O que mostramos ao utilizador?
22.4124°C, precisão é tudo.
Usamos `Math.round()` para mostrar 22°C, que é o que as pessoas esperam ver numa previsão.
Cortamos a string nos primeiros 2 caracteres.
18. Classes e Eventos: Porque usamos Arrow Functions `() => {}` nos event listeners dentro da classe?
Porque são mais curtas.
Para manter o contexto do `this` apontado para a Classe e não para o elemento HTML que foi clicado.
É a única maneira de escrever funções.
19. Segurança: Se a API exigisse uma Chave Secreta (API Key), onde a deveríamos guardar num projeto real?
Diretamente no código JS visível a todos.
Num ficheiro `.env` no servidor (Backend), nunca exposta no Frontend.
Num comentário HTML.
20. Polimento Final: O que falta para o site ser acessível a invisuais?
Nada, eles não usam computadores.
Garantir contraste de cores, usar HTML semântico e adicionar atributos `aria-label` ou `alt` em elementos visuais.
Aumentar a fonte.
🔓 Código Fonte da Solução Profissional
Queres ver como um profissional resolve este problema?
Insere a password de acesso (exclusiva para alunos).
Password Incorreta!
⚠️ AVISO DE PLÁGIO:
Se o teu projeto final for uma cópia integral deste código, será anulado.
Este código serve apenas para consulta, correção de erros e aprendizagem. Escreve a tua própria versão.
Estrutura da Solução Class-Based:
// 1. CONFIGURAÇÃO (Dados estáticos)
const CITIES = [...];
// 2. CLASSE WEATHERAPP
class WeatherApp {
constructor() {
// Selecionar elementos do DOM
this.dom = { ... };
this.init();
}
init() {
// Renderizar listas e listeners
}
// 3. LOGICA ASSINCRONA (Data Fetching)
async searchCity(query) {}
async loadWeather(city) {}
// 4. LOGICA DE UI (DOM Manipulation)
updateUI(data) {}
renderList(cities) {}
}
📝 Como funciona este código?
Usámos tudo o que aprendeste até agora:
Classes: WeatherApp gere todo o estado e lógica.
Async/Await e Fetch: Para falar com a API da Open-Meteo.
DOM: Para atualizar o HTML dinamicamente.
Eventos: Para detetar a escrita no input e cliques.