COVID19 Lockdown Dev Log – Day 28, Webserver In NodeJs Using Express.js and Handlebars

What I Worked On

Setting up a server in NodeJs using the Express.js framework. The end goal is to hook it up to the Weather App, which at the time of writing, only works through the commandline. Click here to check out the repo.

What I Learned

Configuring Express with routes and using Handlebars as a templateengine.

Let’s first install Express and Handlebars

npm i express hbs

Then let’s look at the folder structure I made for the project (nodemoduels, package.json, and package-lock.json are left out):

webserver
-public
 --css
 --img
 --js
-src
 --app.js
-templates
 --partials
 --views

The ‘public’ folder contains all the static files. The ‘src’ contains the Express configuration and ‘templates’ contains the views that will be presented to the user.

Let’s go into ‘app.js’ and configure routes with Express and which templateengine to use for views:

const path = require('path');
const express = require('express');
const hbs = require('hbs');

const app = express()

// use 'path' module to define an absolute path to the 'public' folder
const publicPath = path.join(__dirname, '../public')

// define a custom path/folder for holding the templateengine views
const viewsPathCustom = path.join(__dirname, '../templates/views')

// define path for partials
const partialsPath = path.join(__dirname, '../templates/partials')

// set templateengine to be Handlebars ('hbs')
app.set('view engine', 'hbs')

// Instead of having the default 'views' folde, we set a custom folder for 'views'
app.set('views', viewsPathCustom)

// let 'hbs' know where to find partials
hbs.registerPartials(partialsPath)

//use express.static() to serve static files. In this case our /public folder
app.use(express.static(publicPath))

I left the comments to briefly explain what is happening 😀 Now the configuration is done, almost. Let’s setup a route and which portnumber to use for localhost:

app.get('', (req, res) => {
    //use '.render' to render views. No need to add the file extension to the name.
    //the second argument is an object that the view can access
    res.render('index', {
        title: 'Weather App',
        name: 'André Larsen'
    })
})


//start up the server and listen on a specific port
app.listen(3000, () => {
    console.log('Server is up on port 3000')
})

‘app.get()’ function tells the server what to do when a user requests a specific URL. The URL can return HTML or JSON. The function takes two arguments – a string and a function. The string is the route (in this case it’s empty which is used when you serve the index/root page), and the function is where we describe what to do once a user accesses this route. The function takes two arguments. The first is an object with info about the incoming request to the server. The second is the response, which contains a bunch of methods that we can use to send a response back to the one who requests the URL. In this case we use the ‘res.render()’ to send back a HTML file and an object with the data.

Let’s look at the index.html from the ‘templates/views’ folder that Handlebars will serve when we request it:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="/css/style.css">
    <link rel="icon" href="/img/weathericon.png">
    <script src="/js/app.js"></script>
    <title>Weather App</title>
</head>
<body>
    {{>header }}
    {{>footer }}
</body>
</html>

Handlebars injects the header and footer into the HTML, which both are partials in this case. Let’s look at the {{>header }} partial from ‘templates/partials’:

<h1>{{title}}</h1>

<header>
    <a href="/">Weather</a>
    <a href="/about">About</a>
    <a href="/help">Help</a>
</header>

The ‘title’ in the <h1> tag receives the data from the object passed in the ‘res.render()’ method. The footer partial is very similar so I’ll leave it out of here. So, with all this in place, let’s see how the index.html will look on our local server 😀 :

This was a small intro to Express and Handlebars in NodeJs. To keep the post from getting any longer I won’t go over the rest of the routes that are configured, but it’s basically the same as the one we actually look into in this post. 😀

Tomorrow I will have the Weather App completed with a frontend and hosted online! 😀

What Distracted Me During The Day

  • GF needing input on our weekly meal plan 😀

Resources