# GoWeather This is a simple weather application built with Go, featuring a web-based GUI. The app allows users to enter a city name and view the current temperature and weather conditions for that location. ## Table of Contents 1. [Features](#features) 2. [Prerequisites](#prerequisites) 3. [Installation](#installation) 4. [Usage](#usage) 5. [Code Structure](#code-structure) 6. [How It Works](#how-it-works) 7. [Customization](#customization) 8. [Contributing](#contributing) 9. [License](#license) ## Features - Web-based user interface - Real-time weather data fetching - Display of temperature and weather conditions for a specified city ## Prerequisites - Go (version 1.16 or later) - OpenWeatherMap API key ## Installation 1. Clone this repository or download the source code. 2. Navigate to the project directory. 3. Replace `"YOUR_API_KEY_HERE"` in `main.go` with your actual OpenWeatherMap API key. ## Usage 1. Open a terminal and navigate to the project directory. 2. Run the following command to start the server: ```bash go run main.go ``` 3. Open a web browser and go to `http://localhost:8080`. 4. Enter a city name in the input field and click "Get Weather" to see the current weather information. ## Code Structure The project consists of two main files: 1. `main.go`: The Go server that handles API requests and serves the web interface. 2. `index.html`: The HTML file that provides the user interface. ### main.go This file contains the Go code for the server. Here's a breakdown of its main components: #### WeatherData struct ```go type WeatherData struct { Main struct { Temp float64 `json:"temp"` } `json:"main"` Weather []struct { Description string `json:"description"` } `json:"weather"` } ``` This struct defines the structure for parsing the JSON response from the OpenWeatherMap API. It extracts the temperature and weather description from the API response. #### main() function ````go func main() { http.HandleFunc("/", serveHome) http.HandleFunc("/weather", handleWeather) fmt.Println("Server is running on http://localhost:8080") log.Fatal(http.ListenAndServe(":8080", nil)) } ```` The main() function sets up the HTTP server: It registers two route handlers: one for the home page ("/") and one for weather data requests ("/weather"). It starts the server on port 8080 and logs any fatal errors. #### serveHome() function ````go func serveHome(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "index.html") } ```` This function serves the index.html file when a request is made to the root ("/") of the server. #### handleWeather() function ````go func handleWeather(w http.ResponseWriter, r *http.Request) { city := r.URL.Query().Get("city") if city == "" { http.Error(w, "City parameter is required", http.StatusBadRequest) return } err := godotenv.Load(".env") if err != nil { log.Fatalf("Error loading .env file: %s", err) } apiKey := os.Getenv("openWeatherKey") url := fmt.Sprintf("http://api.openweathermap.org/data/2.5/weather?q=%s&appid=%s&units=metric", city, apiKey) resp, err := http.Get(url) if err != nil { http.Error(w, "Error fetching weather data", http.StatusInternalServerError) return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { http.Error(w, "Error reading response body", http.StatusInternalServerError) return } var weatherData WeatherData err = json.Unmarshal(body, &weatherData) if err != nil { http.Error(w, "Error parsing JSON", http.StatusInternalServerError) return } response := struct { Temperature float64 `json:"temperature"` Condition string `json:"condition"` }{ Temperature: weatherData.Main.Temp, Condition: weatherData.Weather[0].Description, } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) } ```` The handleWeather() function processes weather data requests: 1) It extracts the city name from the query parameters. 2) It constructs the OpenWeatherMap API URL with the city name and API key. 3) It sends a GET request to the API and reads the response. 4) It parses the JSON response into the WeatherData struct. 5) It creates a new struct with the relevant weather information (temperature and condition). 6) Finally, it sends this data back to the client as a JSON response. ### index.html This file contains the HTML, CSS, and JavaScript for the user interface. Key components include: #### HTML Structure ```html
Temperature: ${data.temperature}°C
Condition: ${data.condition}
`; }) .catch(error => { console.error('Error:', error); const weatherInfo = document.getElementById('weatherInfo'); weatherInfo.innerHTML = 'Error fetching weather data
'; }); } ``` This function is called when the user clicks the "Get Weather" button: 1. It retrieves the city name from the input field. 2. It sends a fetch request to the `/weather` endpoint with the city name. 3. When it receives the response, it updates the `weatherInfo` div with the temperature and weather condition. 4. If there's an error, it displays an error message. ## How It Works 1. The user enters a city name and clicks "Get Weather". 2. The JavaScript function `getWeather()` sends a request to the `/weather` endpoint of the Go server. 3. The Go server receives the request and fetches weather data from the OpenWeatherMap API. 4. The server processes the API response and sends back the relevant weather information as JSON. 5. The JavaScript in the browser receives this data and updates the HTML to display the weather information. ## Customization You can customize this app by: - Modifying the HTML and CSS in `index.html` to change the appearance of the app. - Adding more weather data fields in both the Go code and HTML to display additional information. - Implementing error handling for cases like invalid city names or API errors. ## Contributing Contributions to improve the app are welcome. Please feel free to submit a Pull Request. ## License This project is open source and available under the [MIT License](LICENSE).