Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions web/weatherapp/solution/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# OpenWeather API Key
# Get your free API key from: https://openweathermap.org/api
WEATHER_API_KEY=your_api_key_here
22 changes: 22 additions & 0 deletions web/weatherapp/solution/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Environment variables
.env
.env.local
.env.*.local

# Dependencies
node_modules/

# Logs
logs
*.log
npm-debug.log*

# OS files
.DS_Store
Thumbs.db

# IDE
.vscode/
.idea/
*.swp
*.swo
100 changes: 100 additions & 0 deletions web/weatherapp/solution/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# 🌦️ Weather CLI

A command-line interface tool to fetch real-time weather data from OpenWeather API.

## ✨ Features

- 🌍 Search weather by city name
- 🌡️ Display temperature, humidity, wind speed, and more
- 🔐 Secure API key management using environment variables
- 🛡️ Comprehensive error handling:
- Invalid city names
- Network connectivity issues
- Invalid API keys
- API errors
- ⏳ Async/Await based API requests
- 🧠 Clean ES6+ JavaScript structure

## 🚀 Installation

1. Clone the repository
2. Install dependencies:
```bash
npm install
```
3. Create a `.env` file based on `.env.example`:
```bash
cp .env.example .env
```
4. Add your OpenWeather API key to `.env`:
```
WEATHER_API_KEY=your_actual_api_key
```
Get your free API key from: https://openweathermap.org/api

## 📖 Usage

Run the CLI tool:
```bash
npm start
```

Or:
```bash
npm run dev
```

Then enter any city name to get its current weather:
```
🌍 Enter city name (or "exit" to quit): London
```

## 🧪 Error Handling

The CLI handles various error scenarios:

✅ **Valid City**
```
🌍 Enter city name: London
🌦️ Weather in London, GB
🌡️ Temperature: 15°C
```

❌ **Invalid City**
```
🌍 Enter city name: InvalidCity123
🌍 City "InvalidCity123" not found. Please check the spelling and try again.
```

⚠️ **Network Issues**
```
🌐 Network error. Please check your internet connection.
```

🔐 **Invalid API Key**
```
🔐 Invalid API key. Please check your WEATHER_API_KEY in .env file.
```

## 🏗️ Project Structure

```
weather-cli/
├── index.js # Main CLI application
├── package.json # Project dependencies and scripts
├── .env # Environment variables (not committed)
├── .env.example # Template for environment variables
├── .gitignore # Git ignore rules
└── README.md # This file
```

## 🛠️ Technologies Used

- Node.js
- OpenWeather API
- ES6+ JavaScript (async/await, destructuring, modules)
- dotenv for environment variable management

## 📝 License

ISC
107 changes: 107 additions & 0 deletions web/weatherapp/solution/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import 'dotenv/config';
import readline from 'readline';

const API_KEY = process.env.WEATHER_API_KEY;
const BASE_URL = `http://api.weatherapi.com/v1/current.json?key=${API_KEY}`;

// Create readline interface for user input
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});

/**
* Fetch weather data from WeatherAPI.com
* @param {string} city - City name to search
* @returns {Promise<Object>} Weather data
*/
async function fetchWeatherData(city) {
if (!API_KEY) {
throw new Error('❌ API key not found. Please check your .env file.');
}

const url = `${BASE_URL}&q=${encodeURIComponent(city)}`;

try {
const response = await fetch(url);
const data = await response.json();

// Handle API errors (weatherapi.com returns error in response body)
if (data.error) {
if (data.error.code === 1006) {
throw new Error(`🌍 City "${city}" not found. Please check the spelling and try again.`);
}
if (data.error.code === 2006) {
throw new Error('🔐 Invalid API key. Please check your WEATHER_API_KEY in .env file.');
}
throw new Error(`⚠️ API Error: ${data.error.message || 'Unknown error occurred'}`);
}

if (!response.ok) {
throw new Error(`⚠️ HTTP Error: ${response.status} ${response.statusText}`);
}

return data;
} catch (error) {
// Handle network errors
if (error.message.includes('fetch')) {
throw new Error('🌐 Network error. Please check your internet connection.');
}
throw error;
}
}

/**
* Display weather information in a formatted way
* @param {Object} data - Weather data from WeatherAPI.com
*/
function displayWeather(data) {
const { location, current } = data;

console.log('\n' + '='.repeat(50));
console.log(`🌦️ Weather in ${location.name}, ${location.country}`);
console.log('='.repeat(50));
console.log(`🌡️ Temperature: ${current.temp_c}°C (feels like ${current.feelslike_c}°C)`);
console.log(`📊 Condition: ${current.condition.text}`);
console.log(`💧 Humidity: ${current.humidity}%`);
console.log(`💨 Wind Speed: ${current.wind_kph} km/h`);
console.log(`🔽 Pressure: ${current.pressure_mb} mb`);
console.log('='.repeat(50) + '\n');
}

/**
* Prompt user for city and fetch weather
*/
function askForCity() {
rl.question('🌍 Enter city name (or "exit" to quit): ', async (city) => {
city = city.trim();

if (city.toLowerCase() === 'exit' || city.toLowerCase() === 'quit') {
console.log('👋 Thank you for using Weather CLI!');
rl.close();
return;
}

if (!city) {
console.log('⚠️ Please enter a valid city name.');
askForCity();
return;
}

try {
console.log(`\n🔍 Fetching weather data for "${city}"...`);
const weatherData = await fetchWeatherData(city);
displayWeather(weatherData);
} catch (error) {
console.error(`\n${error.message}\n`);
}

// Ask for another city
askForCity();
});
}

// Start the CLI
console.log('\n🌦️ Welcome to Weather CLI');
console.log('━'.repeat(50));
askForCity();
28 changes: 28 additions & 0 deletions web/weatherapp/solution/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions web/weatherapp/solution/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "weather-cli",
"version": "1.0.0",
"description": "A CLI tool to fetch weather data from OpenWeather API",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": ["weather", "cli", "openweather", "api"],
"author": "",
"license": "ISC",
"type": "module",
"dependencies": {
"dotenv": "^17.3.1"
}
}