Weather Dashboard
Real API data with search, loading and error states.
Overview
Build a weather dashboard that fetches real data from a public weather API, supports city search, and handles loading, error and empty states cleanly. Learn API integration, data presentation and robust async state management.
The problem
Show live weather for a searched city, handling loading, errors and empty states gracefully.
Why it matters
Every real app talks to an API; this project proves you can integrate external data and handle the real-world states that come with it.
What you'll build
- A live weather dashboard
- Search with debounce
- Loading/error/empty states
- Responsive data cards
What you'll learn
- API integration
- Async UI state
- Debounced search
- Data presentation
Business problem
Users need current, trustworthy weather with graceful handling of bad input or outages.
Technical problem
Integrate a third-party API and render its data with proper state management.
When you're done: A responsive weather dashboard that reliably queries and presents live data.
Requirements
User requirements
- Search by city
- See current conditions and forecast
- Get clear feedback on errors
- See loading state
System requirements
- Use a public weather API
- Graceful error and empty states
Functional requirements
- City search
- Current weather display
- Forecast list
- Loading state
- Error and empty states
Non-functional requirements
- Responsive
- Clear async states
- Debounced search
Technical requirements
- Async fetch with error handling
- Debounced input
- Reusable result components
Security requirements
- No API key committed
- Sanitize displayed data
Operational requirements
- Handle API rate limits and failures
Constraints
- Frontend only
- Free-tier public API
Success criteria
- Search returns accurate conditions
- Network failure shows a friendly error
- Loading state is visible
Flows
Request Flow
- 1
Browser
User searches a city.
- 2
Application
Debounces and queries the weather API.
- 3
Weather API
Returns conditions and forecast.
- 4
Application
Renders loading, error or results.
Project Structure
Root of the client application source.
Setup
- 1
Prerequisites
You need the tools required by JavaScript, HTML, CSS installed and available on your PATH.
- 2
Clone project
Clone the repository locally.
1. Clone the repositorygit clone <your-repo-url> <project-folder> - 3
Install dependencies
Install the project dependencies.
1. Initialize a Node.js projectLinux / Windowsnpm init -yExpected
Creates a package.json with defaults.
If it fails
command not found: npm
Fix
Install Node.js LTS from the official site, then reopen your terminal.
- 4
Configure environment
Set the environment variables documented for this project. Never commit secrets.
1. Create the environment filecp .env.example .env # then edit values - 5
Start project
Run the development command and confirm it starts.
1. Start the development serverLinux / Windowsnpm run devExpected
Dev server starts; watch terminal for the local URL.
If it fails
Port 3000 is already in use
Fix
Run on another port: npm run dev -- --port 3001, or stop the conflicting process.
- 6
Verify
Open the printed local URL and confirm the primary flow works.
Build Phases
0 of 6 phases complete
Objective: Establish the next milestone of the client-side interface.
What changes: The project advances to the next coherent state, keeping the previous milestones working.
Files touched
Relevant source and configuration files for this milestone.Run
1. Initialize a Node.js projectLinux / Windowsnpm init -yExpected
Creates a package.json with defaults.
If it fails
command not found: npm
Fix
Install Node.js LTS from the official site, then reopen your terminal.
Tasks
- Implement the specific behaviour required for this milestone.
- Verify the previous milestone still works.
Validate: The milestone behaves as expected and does not break existing functionality.
Common mistakes
- • Skipping validation and moving on before confirming the milestone works.
Objective: Establish the next milestone of the client-side interface.
What changes: The project advances to the next coherent state, keeping the previous milestones working.
Files touched
Relevant source and configuration files for this milestone.Run
1. Install the javascript packageLinux / Windowsnpm install javascriptExpected
Adds javascript to node_modules and package.json.
If it fails
npm ERR! network / EACCES
Fix
Check your network or run with sudo on Linux/macOS; on Windows run the terminal as Administrator.
Tasks
- Implement the specific behaviour required for this milestone.
- Verify the previous milestone still works.
Validate: The milestone behaves as expected and does not break existing functionality.
Common mistakes
- • Skipping validation and moving on before confirming the milestone works.
Objective: Establish the next milestone of the client-side interface.
What changes: The project advances to the next coherent state, keeping the previous milestones working.
Files touched
Relevant source and configuration files for this milestone.Run
1. Start the development serverLinux / Windowsnpm run devExpected
Dev server starts; watch terminal for the local URL.
If it fails
Port 3000 is already in use
Fix
Run on another port: npm run dev -- --port 3001, or stop the conflicting process.
Tasks
- Implement the specific behaviour required for this milestone.
- Verify the previous milestone still works.
Validate: The milestone behaves as expected and does not break existing functionality.
Common mistakes
- • Skipping validation and moving on before confirming the milestone works.
Objective: Establish the next milestone of the client-side interface.
What changes: The project advances to the next coherent state, keeping the previous milestones working.
Files touched
Relevant source and configuration files for this milestone.Run
1. Build the application for productionLinux / Windowsnpm run buildExpected
A production bundle is emitted to the output directory.
If it fails
Build fails with a type or syntax error
Fix
Read the error message, fix the referenced file, and re-run the build.
Tasks
- Implement the specific behaviour required for this milestone.
- Verify the previous milestone still works.
Validate: The milestone behaves as expected and does not break existing functionality.
Common mistakes
- • Skipping validation and moving on before confirming the milestone works.
Objective: Establish the next milestone of the client-side interface.
What changes: The project advances to the next coherent state, keeping the previous milestones working.
Files touched
Relevant source and configuration files for this milestone.Tasks
- Implement the specific behaviour required for this milestone.
- Verify the previous milestone still works.
Validate: The milestone behaves as expected and does not break existing functionality.
Common mistakes
- • Skipping validation and moving on before confirming the milestone works.
Objective: Establish the next milestone of the client-side interface.
What changes: The project advances to the next coherent state, keeping the previous milestones working.
Files touched
Relevant source and configuration files for this milestone.Tasks
- Implement the specific behaviour required for this milestone.
- Verify the previous milestone still works.
Validate: The milestone behaves as expected and does not break existing functionality.
Common mistakes
- • Skipping validation and moving on before confirming the milestone works.
Commands
npm init -yExpected
Creates a package.json with defaults.
If it fails
command not found: npm
Fix
Install Node.js LTS from the official site, then reopen your terminal.
npm install javascriptExpected
Adds javascript to node_modules and package.json.
If it fails
npm ERR! network / EACCES
Fix
Check your network or run with sudo on Linux/macOS; on Windows run the terminal as Administrator.
npm run devExpected
Dev server starts; watch terminal for the local URL.
If it fails
Port 3000 is already in use
Fix
Run on another port: npm run dev -- --port 3001, or stop the conflicting process.
npm run buildExpected
A production bundle is emitted to the output directory.
If it fails
Build fails with a type or syntax error
Fix
Read the error message, fix the referenced file, and re-run the build.
Testing
Unit tests
Core logic and pure functions behave correctly.
npm init -ySuccess: All unit tests pass without errors.
Integration tests
Components integrate correctly with data sources and services.
npm testSuccess: Integration tests pass for the primary flows.
API tests
Endpoints respond to valid and invalid input correctly.
npm testSuccess: API tests cover happy and failure paths.
End-to-end tests
A user can complete the primary journey end to end.
npm run test:e2eSuccess: The main user journey completes successfully.
Security tests
No obvious security regressions are introduced.
npm auditSuccess: No high or critical vulnerabilities.
Debugging & Troubleshooting
Port already in use at startup
Why: Another process is binding the same port your app wants.
Check: List what is using the port.
lsof -i :3000 # Linux/macOS | netstat -ano | findstr :3000 # Windows
Fix: Free the port or start your app on a different port.
Prevent: Choose uncommon ports and document them in the README.
Environment variable missing or undefined
Why: A required value was not loaded into the runtime.
Check: Print the variable or inspect the config loader.
echo $MY_VAR # Linux/macOS | echo %MY_VAR% # Windows
Fix: Add the variable to your .env file and restart the process.
Prevent: Fail fast at startup when required env vars are absent.
API request times out
Why: An upstream call is slow or the network is blocked.
Check: Time a direct request against the upstream.
curl -w 'time_total: %{time_total}\n' http://upstream/healthFix: Add timeouts and retries to the client; verify the upstream is up.
Prevent: Set explicit timeouts and circuit breakers on outbound calls.
Dependency fails to install or run
Why: Version conflicts or an incompatible runtime.
Check: Inspect the error and the installed versions.
npm ls <pkg>
Fix: Align versions or clear the lockfile and reinstall.
Prevent: Commit a lockfile and use the same Node version everywhere.
Security
Security is treated as a core requirement: input is validated, secrets are protected, and dependencies are kept up to date.
Input validation
Validate and sanitize all user input before use.
Secrets management
Store secrets in environment variables, never in source.
Dependency hygiene
Regularly audit dependencies for known vulnerabilities.
Observability
Logs
- Structured request logs with correlation IDs
- Application-level error logs
Metrics
- Request latency
- Error rate
- Throughput
Traces
- Request tracing across the API and data layer
Health checks
- A /health endpoint reporting readiness
Alerts
- High error rate alert
- Latency threshold alert
Dashboards
- A dashboard showing requests, latency and errors
SLIs
- Availability — Fraction of successful requests over the window
- Latency — P95 response time
SLOs
- Availability — 99.9% over 30 days
- Latency — P95 under 500ms
Deployment
- 1
Prepare for deployment
Build the production artifact.
1. Build for productionnpm run build - 2
Deploy
Deploy to the project target platform following its documented steps.
1. Deploynpm run deploy # or the platform-specific command - 3
Verify
Confirm the deployed application responds and its health check passes.
1. Check healthcurl -I https://<your-deployed-url>
Documentation
Project Overview
Build a weather dashboard that fetches real data from a public weather API, supports city search, and handles loading, error and empty states cleanly. Learn API integration, data presentation and robust async state management. This is a intermediate ui project in the client-side interface space, built to demonstrate real engineering, not just copied code.
What You Will Build
- A live weather dashboard - Search with debounce - Loading/error/empty states - Responsive data cards
Problem Statement
Users need current, trustworthy weather with graceful handling of bad input or outages. Integrate a third-party API and render its data with proper state management.
Technology Stack
JavaScript, HTML, CSS
Installation
Clone the repository and install dependencies with the documented commands.
Local Development
Run the development command and open the printed local URL.
Testing
Run the test commands documented in the Testing section and confirm they pass.
Deployment
Follow the documented deployment steps for this project's target platform.
Interview Explanation
Use the Interview section to explain the architecture, technology choices and trade-offs.
Build Process
Phases guide the build in 6 checkpoints. Complete each and validate before moving on.
Interview Prep
30-second pitch
I built Weather Dashboard — show live weather for a searched city, handling loading, errors and empty states gracefully. It uses JavaScript, HTML, CSS and solves users need current, trustworthy weather with graceful handling of bad input or outages.
2-minute walkthrough
Build a weather dashboard that fetches real data from a public weather API, supports city search, and handles loading, error and empty states cleanly. Learn API integration, data presentation and robust async state management. The core requirements were City search, Current weather display, Forecast list. I structured the work around Fetch and process external data, Manage async UI states, Implement search with debounce and validated the result with the documented tests.
Architecture
Because this is a frontend project, the architecture is concentrated in client-side interface rather than a distributed system.
Why these technologies
I chose JavaScript, HTML, CSS because they are the pragmatic, well-supported tools best suited to building a ui of this kind.
Why this architecture
The structure exists to keep concerns separated, make each piece testable, and scale the project cleanly as requirements grow.
At scale
At scale I would introduce caching, move to a service boundary structure, add proper observability, and enforce stricter contracts between components.
What can fail
The data source becomes unavailable, A dependency introduces a breaking change, Performance degrades under load, Configuration drift between environments
Monitoring
Monitoring is covered in the Observability section, focusing on requests, latency, errors and health checks.
Security
Security was handled by validating input, protecting secrets, and following the practices listed in the Security section.
Deployment strategy
Deployment follows the steps in the Deployment section for the target platform, with a health check to confirm success.
What I'd do differently
With more time I would add deeper test coverage, stronger observability, and automated deployment.
Practice Q&A
Why did you build Weather Dashboard?
To demonstrate Fetch and process external data and Manage async UI states on a real, portfolio-worthy project.
What was the hardest part?
Coordinating the pieces so each stays correct as the project grows, and validating end to end.
How do you handle failure and scale?
By designing for correctness first and adding resilience once the core works.
Extensions
- Add deeper test coverage
- Add observability and alerting
- Harden security
- Automate deployment