# Creating a weather app in Express Js using OpenWeatherMap API

Welcome back! In this post, we are going to make a weather app using Express JS, that will fetch weather data of a particular location with the help of **OpenWeatherMap** API. 

The API is **free** to use and you can get your API keys from the link below. Just signup and you are good to go.

[Сurrent weather and forecast - OpenWeatherMap](https://openweathermap.org)

Now we can copy the API key that we need to fetch the weather of a new location. Go to the API section and select the **Current Weather Data **and click **Subscribe**.

Now click on get API key under the free plan and copy the key which they provided.

Once you are done with the account creation and copying the key, we can now start with the code.

Open your terminal and navigate to the location where you want to create your Node Js app.

Next, we need to create a new directory and name it **weatherapp **or you can name it as per your choice.

`mkdir weatherapp`

Navigate to this directory.

`cd weatherapp`

Now, we need to set up a node js project in this directory. Write the following command in your terminal and follow the instructions as shown there.

`npm init`

Open your weatherapp directory in you favourite text editor and we can now move on to the code.

Create a new file inside your weatherapp directory and name it `app.js`.

This is going to be the starting file of our app. We'll come back to this file once we are done with the installation of the requires packages.

Now, we'll install all the required packages for this project.

The first thing we need is to install is Express and body-parser.

Run the following command in your terminal inside your project's directory.

`npm install express --save`

`npm install body-parser`

For templates, we are going to use EJS. You can read more about ejs on their official docs from the link below.

[EJS -- Embedded JavaScript templates](https://ejs.co)

We'll first start with the installation of ejs in our project with the help of the following command.

`npm install ejs`

Next, we need to create a new directory named `views` in our root directory.

Inside the views directory, we are going to store all of our templates.

Now create a new file inside views directory and name it `index.ejs`.

Copy the following code and paste it in your `index.ejs` file.

    <!DOCTYPE html>
    <html lang="en">
    
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Weatherly</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
          integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
        <link rel="stylesheet" href="style.css">
      </head>
    
      <body>
        <% if (data === '') { %>
        <div class="container mt-5 col-lg-6">
          <p class="display-4 text-center">Weatherly🌤! by <a href="https://pratiksah.com" target="_blank">Pratik</a></p>
          <div class="card">
            <div class="card-body">
              <h5 class="card-title">Search weather of your location</h5>
              <form action="/" method="post">
                <div class="form-group">
                  <input type="text" class="form-control" name="location" placeholder="Location">
                  <p class="display-5 mt-3 text-muted">Default location is Purnia, In</p>
                </div>
                <button type="submit" class="btn btn-primary">Go</button>
              </form>
            </div>
          </div>
        </div>
        <% } else if (data === '0') { %>
        <div class="container mt-5">
          <div class="card">
            <div class="card-body">
              <p class="card-title">Oops! Lost in space🚀, try locations from Earth🌏 !</p>
            </div>
          </div>
          <div class="text-center">
            <a href="/" class="btn btn-primary mt-5 mx-auto">New location</a>
          </div>
        </div>
        <% } else { %>
        <div class="container mt-5">
          <p class="display-4 text-center">Weatherly! by <a href="https://pratiksah.com" target="_blank">Pratik</a></p>
          <div class="card">
            <div class="card-body">
              <h5 class="card-title">Weather in <%= data.name %>, <%= data.sys.country %></h5>
              <p class="text-muted">Lat: <%= data.coord.lat %>, Lon: <%= data.coord.lon %></p>
              <img class="float-right" src="http://openweathermap.org/img/wn/<%= data.weather[0].icon %>@2x.png" alt="icon">
              <p class="display-1"><%= data.main.temp%><sup>o</sup>C</p>
              <span class="text-muted">Feels like <%= data.main.feels_like %><sup>o</sup>C</span>
              <h5 class="text-capitalize font-weight-bold"><%= data.weather[0].description %></h5>
              <div class="overflow-x">
                <span class="pr-5 inf"><i class="fas fa-wind"></i> Wind <%= data.wind.speed %> m/sec</span>
                <span class="pr-5 inf"><i class="fas fa-paper-plane"></i> Pressure <%= data.main.pressure %> mb</span>
                <span class="pr-5 inf"><i class="fas fa-tint"></i> Humidity <%= data.main.humidity %>%</span>
                <span class="pr-5 inf"><i class="fas fa-eye"></i> Visibility <%= data.visibility/1000 %> km</span>
                <span class="pr-5 inf"><i class="fas fa-cloud"></i> Cloudiness <%= data.clouds.all %>%</span>
              </div>
            </div>
          </div>
          <div class="text-center">
            <a href="/" class="btn btn-primary mt-5 mx-auto">New location</a>
          </div>
        </div>
        <% } %>
        <script src="https://kit.fontawesome.com/ad862d8e11.js" crossorigin="anonymous"></script>
      </body>
    
    </html>

Now, come back to our app.js file and import express, https and body-parser.

    const express = require('express')
    const https = require('https')
    const bodyParser = require('body-parser')

Now, we'll create a new express app.
`const app = express()`

Now, we'll set up our view-engine to ejs.
`app.set('view engine', 'ejs')`

Now we'll create a middleware that will help us in parsing the content of the form submitted.

    app.use(bodyParser.urlencoded({extended: true}))

Next, we will be serving a form with an input field that will take location as an input.

The above `ejs` file will help us to serve a form that will take input of a location from the user.

Here I have used an external CSS, if you want to use that, here is the code to it. 

    .fas {
      width: 1.3em !important;
    }
    
    @media only screen and (max-width: 800px) {
      .inf {
        display: block !important;
      }
      .display-1 {
        font-size: 3rem;
      }
    }

style.css
This **CSS** file is to be placed inside a `public` directory inside the root directory and if you don't know how to serve a static file in node js using express, you can follow my other post, here is the link to it.

[Serving static files in Node js](/serving-static-files-in-node-js/)

Now, let's write our complete code for `index.js` file. Here is the code for the api call.

    const express = require('express')
    const https = require('https')
    const bodyParser = require('body-parser')
    
    
    const app = express()
    
    // telling my app to use ejs as the default template engine
    app.set('view engine', 'ejs')
    
    app.use(bodyParser.urlencoded({
      extended: true
    }))
    
    // code to serve the static files
    app.use(express.static("public"))
    
    app.get('/', (req, res) => {
      res.render('index', {data: ''});
    })
    
    app.post('/', (req, res) => {
      const location = req.body.location ? req.body.location : "Purnia";
      const appId = "Your_API_Key_Here";
      const url = "https://api.openweathermap.org/data/2.5/weather?q=" + location + "&appid=" + appId + "&units=metric";
      https.get(url, (response) => {
        if (response.statusCode === 200) {
          response.on("data", (data) => {
            const weatherData = JSON.parse(data);
            res.render('index', {data: weatherData});
          })
        } else {
          res.render('index', {data: "0"})
        }
      })
    })
    
    app.listen(process.env.PORT || 80)

Once you are done with the final code of `app.js` you can now start your server and it will launch your app.

To start your server, type `npm start` and this will run ther server on port `80`.

Now, open your browser and go to `http://localhost/`, you'll see your app running. Enter any location and it will show you the weather of that location.

[Here is the link](https://intense-spire-12796.herokuapp.com/) to the app which I made using OpenWeatherMap and hosted on Heroku for free.

Well, this was all for today's post and if you found it helpful, please leave a like & comment and in my next post, I'll teach you how you can create your own todo app with jQuery and localStorage.

Thanks for your time and I'll meet you in my next post. Take care and happy coding🙂!
