codeburst

Bursts of code to power through your day. Web Development articles, tutorials, and news.

Follow publication

Build a Weather Website in 30 minutes with Node.js + Express + OpenWeather

Got 30 minutes? Learn to build a web app where users can type in a city name and get real-time weather data instantly displayed on their screen.

Brandon Morelli
codeburst
Published in
10 min readJun 26, 2017
weather — image via unsplash.com

Click Here to see a live example of what we’ll be building.

Last week I published an article on how to create a console weather app with Node.js. That’s great and all, but many readers asked: How do we go from a console application to a fully-functioning website? That’s what I’m going to teach you today.

This tutorial is somewhat of a continuation of of last weeks tutorial: Build a simple Weather App with Node.js in just 16 lines of code. It’s beneficial to read through that tutorial (about 15 minutes) then come back here when you’re done. If you’d rather just jump in, go for it!

Here’s what it’ll look like

Pre-Project Setup

Here’s what you’ll need:

Project Setup

Before we begin, all the code for this project can be found in the GitHub Repo

  1. Create an empty directory named weather-app.
  2. Open up your console, navigate to our new directory and run npm init.
  3. Fill out the required information to initialize our project.
  4. Within our weather-app directory, create a file named server.js — this file will house the code for our application.

Now that we have all the puzzle pieces, we can start building!

Creating our Server (with Express JS)

First thing we need to do is get our server up and running. We’re going to use Express to accomplish this. Express is a minimalist web framework for Node.js — Express makes it very easy to create and run a web server with Node.

To use express, install it in the console:

npm install --save express

Once installed, we’re going to copy the boilerplate Express starter app from the Express documentation:

const express = require('express')
const app = express()

app.get('/', function (req, res) {
res.send('Hello World!')
})

app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})

Above is an example of the simplest application that we can create with Express. First we require the express package that was just installed. Then, we create an instance named app by invoking Express.

The app.get('/'... means we are specifically focusing on the root URL (/). If we visit the root URL, Express will respond with “Hello World!”.

The app.listen(... shows we are creating a server that is listening on port 3000 for connections.

We can test our server by running:

node server.js// Example app listening on port 3000!

Now open your browser and visit: localhost:3000 and you should see Hello World!

Awesome! You’ve just created a server with Node.js and Express!

Setting up the index view

Instead of responding with text when someone visits our root route, we’d like to respond with an HTML file. For this, we’ll be using EJS (Embedded JavaScript). EJS is a templating language.

In order to use EJS in Express, we need to set up our template engine:

A template engine enables you to use static template files in your application. At runtime, the template engine replaces variables in a template file with actual values, and transforms the template into an HTML file sent to the client. This approach makes it easier to design an HTML page.

The short version is that EJS allows us to interact with variables and then dynamically create our HTML based on those variables! (This will make a lot more sense later in the tutorial)

First, we’ll install ejs in the terminal:

npm install ejs --save

We can then set up our template engine with this line of code (just below our require statements) in our server.js file:

app.set('view engine', 'ejs')

EJS is accessed by default in the views directory. So create a new folder named views in your directory. Within that views folder, add a file named index.ejs. Think of our index.ejs file as an HTML file for now.

Real quick, here’s what our file structure should look like thus far:

|-- weather-app
|-- views
|-- index.ejs
|-- package.json
|-- server.js

Awesome, here’s a boilerplate for our index.ejs file. I’m not going to go over this file as this is not an HTML tutorial, but it should be pretty straight forward as we’re not using any EJS just yet. The html is just a form with one input for a city, and one submit button:

Once you have the above code copied into your index.ejs file, you’re almost done! The final thing we need to do is replace our app.get code:

app.get('/', function (req, res) {
// OLD CODE
res.send('Hello World!')

})

Above is the old code where we send the text ‘Hello World!’ to the client. Instead, we want to send our index.ejs file:

app.get('/', function (req, res) {
// NEW CODE
res.render('index');

})

Instead of using res.send, we use res.render when working with a templating language. res.render will render our view, then send the equivalent HTML to the client.

At this point, wee can test again by running:

node server.js// Example app listening on port 3000!

Now open your browser and visit: localhost:3000 and you should see our index.ejs file being displayed!

What you should see at this point

Adding a CSS File

Yours will look a little less ‘pretty’ than mine. That’s because I’m making use of a css file to style my HTML. Here’s how we get our CSS to work:

You’ll need to add a new folder to our project called public. Within that folder create a css folder, and finally create a file named style.css. Here’s your new file structure:

|-- weather-app
|-- views
|-- index.ejs
|-- public
|-- css
|-- style.css
|-- package.json
|-- server.js

Express wont allow access to this file by default, so we need to expose it with the following line of code:

app.use(express.static('public'));

This code allows us to access all of the static files within the ‘public’ folder.

Finally, we need our CSS. Since this isn’t a CSS course, I’m not going to be going over the specifics, but if you’d like to use my CSS, you can copy it from here.

Setting up our POST Route

By now, your server.js file should look like this:

We have one get route, and then we create our server. However, for our application to work, we need a post route as well. If you look at our index.ejs file, you can see that our form is submitting a post request to the / route:

<form action="/" method="post">

Now that we know where our form is posting, we can set up the route! A post request looks just like a get request, with one minor change:

app.post('/', function (req, res) {
res.render('index');
})

But instead of just responding with the same html template, lets access the name of the city the user typed in as well. For this we need to use an Express Middleware.

Express is a minimalist framework. However, we can make use of Middleware (functions that have access to the req and res bodies) in order to preform more advanced tasks.

We’re going to make use of the body-parser middleware. body-parser allows us to make use of the key-value pairs stored on the req-body object. In this case, we’ll be able to access the city name the user typed in on the client side.

To use body-parser, we must install it first:

npm install body-parser --save

Once installed, we can require it, and then make use of our middleware with the following line of code in our server.js

const bodyParser = require('body-parser');
// ...
// ...
app.use(bodyParser.urlencoded({ extended: true }));

For the scope of this project, it’s not necessary you understand exactly how that line of code works. Just know that by using body-parser we can make use of the req.body object.

Finally, we can now update our post request to log the value of ‘city’ to the console.

app.post('/', function (req, res) {
res.render('index');
console.log(req.body.city);
})

Lets test it!

node server.js// Example app listening on port 3000!

Now open your browser and visit: localhost:3000, type a city name into the field and hit enter!

If you go back to your command prompt, you should see the city name displayed in the prompt! Awesome, you’ve now successfully passed data from the client to the server!

If you can’t get it to work, here’s what your server.js file should look like now:

Finishing app.post

To finish up this project, you’ll need the code from my previous tutorial: Build a simple Weather App with Node.js in just 16 lines of code. I’ve copied in the code below. If you don’t understand what the code is doing, I recommend you go read through my previous tutorial.

What were going to do is make a request to the OpenWeatherMap API in our app.post request. Here’s what the code looks like:

Woah. That’s a lot of new code. Lets break it all down:

1. Setting up our URL:

The first thing we do when we receive the post request is grab the city off of req.body. Then we create a url string that we’ll use to access the OpenWeatherMap API with

app.post('/', function (req, res) {
let city = req.body.city;
let url = `http://api.openweathermap.org/data/2.5/weather?q=${city}&units=imperial&appid=${apiKey}`

2. Make our API call:

Now that we have our URL, we can make our API call. When we receive our callback, the first thing we’re going to do is check for an error. If we have an error, we’re going to render our index page. But notice that I’ve also added in a second argument. res.render has an optional second argument — an object where we can specify properties to be handled by our view ( index.ejs ).

In this instance, I’ve added an error string:

request(url, function (err, response, body) {
if(err){
res.render('index', {weather: null, error: 'Error, please try again'});

3. Display the weather:

Now that we know we have no API error, we can parse our JSON into a usable JavaScript object.

The first thing we’ll do is check to see if weather.main == undefined . The only reason why this would be undefined, is if our user input a string that isn’t a city (‘3’, ‘afefaefefe’, etc.). In this instance, we’ll render the index view, and we’ll also pass back an error.

If weather.main != undefined, then we can finally send back the weather to the client! We’ll create a string that clarifies what the weather is, and send that back with the index view.

} else {
let weather = JSON.parse(body)
if(weather.main == undefined){
res.render('index', {weather: null, error: 'Error, please try again'});
} else {
let weatherText = `It's ${weather.main.temp} degrees in ${weather.name}!`;
res.render('index', {weather: weatherText, error: null});
}
}

Using EJS

There’s only one thing left to do at this point… Make use of all those variables we sent back with our res.render call. These variables aren’t available on the client, this is where we finally get to use EJS. There are three possible scenarios that we have in our code:

  1. {weather: null, error: null}
  2. {weather: null, error: ‘Error, please try again’}
  3. {weather: weatherText, error: null}

We need to make two simple changes to our index.ejs to handle these three scenarios. Here’s the code, then I’ll walk you through it:

<% if(weather !== null){ %>
<p><%= weather %></p>
<% } %>
<% if(error !== null){ %>
<p><%= error %></p>
<% } %>

It helps to remember that EJS stands for Embedded JavaScript. With that in mind, EJS has opening and closing brackets: <% CODE HERE %> Anything between the brackets is executed. If the opening bracket also includes an equal sign: <%= CODE HERE ADDS HTML %>, then that code will add HTML to the result.

If you look at our EJS that we’ve added, we’re testing to see if either of our weather, or error variables are null. If they’re both null, nothing happens. However, if one isn’t null (i.e. it has a value), then we will add a paragraph to the screen with the value of the respective variable.

index.ejs

Here’s what your index.ejs should look like:

server.js

Here’s what your server.js should look like:

Run your code

Reminder: all of the code for this project can be found in the GitHub Repo

node server.js// Example app listening on port 3000!

Now open your browser and visit: localhost:3000, type a city name into the field and hit enter! You should see the weather appear on your screen!

You just built a website that makes API calls and responds to the client in real time!

❤ If this post was helpful, please hit the little blue heart!

If tutorials like this interest you and you want to learn more, check out my Best Courses for Learning Full Stack Web Development, or my Three awesome courses for learning Node.js.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in codeburst

Bursts of code to power through your day. Web Development articles, tutorials, and news.

Written by Brandon Morelli

Creator of @codeburstio — Frequently posting web development tutorials & articles. Follow me on Twitter too: @BrandonMorelli