Create A Weather App
Tags: javascript, beginners
Published: 2023-05-13 05:33:24

## Introduction
The Weather App is a simple Realtime weather app which display city weather info from weather API. It is good for beginner to practices coding JavaScript, html, CSS and using public API. To be sure the input city information correctly, I only choose California cities as a list to be changed in selection.

## Feature
The weather app has several features such as selecting city, searching city's weather card, Realtime updating city weather information, changing weather card background color and weather icon. If you want to delete the city's weather card, you just click the cross button on the top right corner. the last is that there a error msg when we cannot fetch data from weather API.
To archive these features, we solve them in code
* 1. get city's location latitude and longitude, using `async` and `await` to get Realtime data.
```js
async function getcitylocation(city){
 const getres = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${city},+${state}&key=${API_key}`)
        const geoData = await getres.json()
        let lat = geoData.results[0].geometry.location.lat;
        let lng = geoData.results[0].geometry.location.lng
}
```
the API_key can be gotten from google cloud console **APIs&Services**; thus, you can apply and enter your key.
After getting the city's point [**latitude**,**longitude**], we use the point to get grid ID and X,Y coordinates.
`https://api.weather.gov/points/{latitude},{longitude}`
Using this [weather.gov](weather.gov) API we can get the city's weather info:
```js
const res = await fetch(`https://api.weather.gov/points/${lat},${lng}`)
        let e = await res.json()
        console.log(e)
        let weatherUrl = `https://api.weather.gov/gridpoints/${e.properties.gridId}/${e.properties.gridX},${e.properties.gridY}/forecast/hourly`
        const response = await fetch(weatherUrl)
        let data = await response.json()
```
Right now we can get the city weather data; however, there is week hourly data collected in the database. To match the Realtime data we need figure out the city time zone to match the Starttime and Endtime in database. The week hourly array data is stored in database. Therefore, find out the index of the array is necessary, which date time matches Starttime and Endtime in relative timezone.
the code `let index = data.properties.periods.findIndex(MatchDateTime)` is to find the city's real time. Moreover, the Function **MatchDateTime()** return true and false into the inner function **findIndex**. 

* 2. Using Realtime data to get weather information such as degrees, isdaytime, shortForecast, windSpeed, windDirection, Temperature, humidity; and then, we assign them into a weatherObj
```js
weatherObj = {
        id: index,
        city: cityName,
        image: forecastPhoto,
        shortForecast: dataObj.shortForecast,
        windSpeed: dataObj.windSpeed,
        windDirection: dataObj.windDirection,
        temperature: dataObj.temperature,
        humidity: dataObj.relativeHumidity.value,
        gridId: GridId,
        gridX: GridX,
        gridY: GridY,
        idName:idName,
        backgroundcolor: color,
        count: 1,
    }
```  

* 3. When we select a city, the new city weather card will be create in the website and stored in json database. The city weather card is rendered in element 'div':
```js
const cityCard = document.createElement('div');
    cityCard.className = 'citycard';
    let idName = weatherObj.city
    idName = idName.replace(" ", '_')
    weatherObj.idName = idName

    cityCard.innerHTML = `
        <div id=${idName}>
        <div class="degrees"><img src = ${weatherObj.image} class = 'forecastphoto'  >${weatherObj.temperature}&deg${unit}</div>
        <div class="place">${weatherObj.city}</div>
        <div class="weather">${weatherObj.shortForecast}</div>
        <div class="wind">Wind: ${weatherObj.windSpeed} | Direction: ${weatherObj.windDirection}</div>
        <div class="humidity">Humidity: ${weatherObj.humidity}% </div>
        <div class="count">the info updated: ${weatherObj.count} times</div>
        </div>
        <button id="clean" class="clean">x</button>
        `
    cityCard.querySelector(`#${idName}`).style.backgroundColor = weatherObj.color
```
 Also, each city's weatherObj will be store in db.json database using fetch method **POST**:
```sh
async function addWeatherCard(WeatherObj) {
    try {
        const res = await fetch("http://localhost:3000/weatherCards", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Accept: "application/json"
            },
            body: JSON.stringify(WeatherObj)
        })
        const item = await res.json()
    } catch (error) {
        console.log(error.message)
    }
}
```
All city's weahter information is store in the db.json, and we use method **PATCH** to update each city's weather infomation per 10 minuntes. All city weather card info updated from weather.gov API. To delete each weather card, I fetch obj with id and use method **DELETE** to delete card element. In the project, we use fetch methd GET, POST, PATCH and DELETE to interact with Database.

* 4. search city weather card by 'search' event listener and use CSS to display or not display weather card. the code is:
```js
document.querySelector("#searchInput").addEventListener("search", SearchCity)
function SearchCity() {
    let val = document.querySelector('#searchInput').value
    let input = val.toLowerCase()
    let x = document.getElementsByClassName('citycard')
    for (let i = 0; i < x.length; i++) {
        if (x[i].children[0].children[1].textContent.toLowerCase().includes(input)) {
            x[i].style.display = "list-item"
            x[i].style.backgroundColor= x[i].children[0].style.backgroundColor
            x[i].style.display= "inline-grid"
        } else {
            x[i].style.display = "none"
        }
    }
}

```
## Wrapping UP
In the project, we can practice how to use map API and weather API in JavaScript to build a weather app. Even we use exteral API, we still use fetch method GET, POST, PATCH, and DELETE to interact with local database and weatherObj data. If you like this project you can get more information and code from my github [weatherAPP](https://github.com/atenliao/WeatherAPP).