Build a Weather App using JavaScript
Tags: javascript, html, css
Published: 2021-05-08 13:46:36

## Let's get started!

to get complete code visit : [GitHub](https://github.com/fahadhassan1213/Weather-Teller)
 
Some basic things we need to understand before creating a weather app are.

- _We need to fetch weather data from a weather forecasting 
   the platform using APIs_ 
- _After fetching data we need to extract our required 
   information from that weather data e.g: **weather_condition, 
   temperature** etc_

### Fetching Weather data using AccuWeather APIs

AccuWeather is an American company that provides international weather forecasting services.

_**Note:** to fetch weather information using APIs from Accuweather we first need to [create a user account](https://developer.accuweather.com/user) on accuweather._

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/66k1y7fsrzi3v15n8o3t.PNG)

Please visit [Accuweather tutorial](https://youtu.be/FLd0w2oBnXY) 

It is a detailed video tutorial on how to get started with AccuWeather and to get APIs, which we are using in our code to fetch weather data.

## Basic HTML Structure and CSS Styling
I have used [bootstrap](https://getbootstrap.com/) for basic styling. To get the HTML and CSS file please visit [GitHub](https://github.com/fahadhassan1213/Weather-Teller)

 

## JavaScript code

Create a new file `forecast.js`

### 1. `forecast.js` File

#### Task# 1

In forecast.js first, you need to initialize your _**API key**_
```js
const key = 'CXhPk82ZAZgV0ngVUWdVBVGePc4qMGqf';
```
After this we need to create two function `getCity()` and `getWeather()`. Using these functions we will fetch the city data and weather_condition of that city from AccuWeather.
```js
const key = 'CXhPk82ZAZgV0ngVUWdVBVGePc4qMGqf';

const getCity = async(city) =>{/*code to fetch the city detail using API*/}

const getWeather = async(id) =>{/*code to fetch the weather detail using API*/}
```

#### Task# 2

In `getCity()` and getWeather() we need to define two variables url and query.

Now initialize these variables as follows.
```js
const getCity = async(city) =>{

    const url = 'https://dataservice.accuweather.com/locations/v1/cities/search';
    const query = `?apikey=${key}&q=${city}`
}

const getWeather = async(id) =>{

    const url = 'https://dataservice.accuweather.com/currentconditions/v1/'
    const query = `${id}?apikey=${key}`
}
``` 

_**Note:** to understand the API key, URL and Query please watch the above given video tutorial_

In the above code, after setting the API key, URLs and Query we need to call the `fetch()` method and pass the `rrl` + `query` as an argument which makes a complete web address resource to access the data. The Fetch API accesses resources across the network. You can make HTTP requests (using GET, POST, and other methods), download, and upload files. `fetch()` starts a request and returns a promise. When the request completes, the promise is resolved with the Response object.
```js
const key = 'CXhPk82ZAZgV0ngVUWdVBVGePc4qMGqf';

const getCity = async(city) =>{

    const url = 'https://dataservice.accuweather.com/locations/v1/cities/search';
    const query = `?apikey=${key}&q=${city}`

    const response = await fetch(url+query);
    const data = await response.json();
    return data[0];

}


const getWeather = async(id) =>{

    const url = 'https://dataservice.accuweather.com/currentconditions/v1/'
    const query = `${id}?apikey=${key}`
    const response = await fetch(url+query);
    const data = await response.json();

    return data[0];
}
```

`getCity()` and `getWeather()` are asynchronous functions since they are marked with the `async` keyword. As `fetch()` return a promise so you have to wait for it to be resolved that's why we have marked it with an `await` keyword.
We are returning the `0-index` of data `return data[0]` because when the promise becomes resolve it will return 2 types of data [0] and [1]. The most accurate one will always be the first one `[0]`, so that's why we are returning `[0]-index` of data   


In the end, we will get a response object in the JSON formate of city details from `getCity()` same is the case with `getWeather()` as they are returning promises we will deal with these promises in the `app.js` file. 

### 2. `app.js` file

In app.js we have a async function named `updateCity()` as shown below
```js
let updateCity = async (city) =>{

    const cityName = await getCity(city);
    const weatherDetail = await getWeather(cityName.Key);

    return{cityName,weatherDetail};
}
```
this function is returning an object having city details and weather details.

because the async function always returns a promise so in the code below we are getting the name of the city from the user and passing the city name as an argument to `updateCity()` function and as we know `updateCity()` function will return a promise so we need to deal with that promise (if the promise is resolved 'then' what? and if it is not resolved 'catch' the error)
```js
getCityForm.addEventListener('submit',e =>{
    e.preventDefault();

    const city = getCityForm.city.value.trim();
    getCityForm.reset();

    updateCity(city)
        .then(data => updateUI(data))
        .catch(err => {
            console.log(alert('Please enter a valid city name'))
            console.log(err);
        })
})
``` 

When the promise becomes resolved we have to update our user interface to show the details to the user.

So in the code, above we pass the resolved promise to the `updateUI()` function(which will update our User Interface)

```js
const updateUI = (data) =>{

    wDetail.classList.remove('d-none')
    cityTime.classList.remove('d-none')
    const cityDetail = data.cityName;
    const weatherDetail = data.weatherDetail;
    degree.textContent = weatherDetail.Temperature.Metric.Value;
    condition.textContent = weatherDetail.WeatherText
    const weatherIconNumber = weatherDetail.WeatherIcon
    icon.setAttribute('src',`icons/${weatherIconNumber}.svg`)
    
    //from weather condition we will get timestamp 
    //So we have to convert it into real time
    const timestamp = weatherDetail.LocalObservationDateTime;
    const now = new Date(timestamp)
    curTime.textContent = now.toLocaleDateString()
    curCity.textContent = cityDetail.EnglishName
    if(weatherDetail.isDayTime){
        curMeridiem.textContent = "Day";
    }else{
        curMeridiem.textContent = 'Night';
    }
}
```

In the `updateUI()` function we are simply first getting the sub details(e.g: Temperature, weather condition, etc) of city and weather details and rendering those details on the screen.

**Hurry! Our Weather app is ready**

## Conclusion

**Thanks for reading this article!**
If you have some queries or want to share something hit a comment below!