Express + Handlebars: How to conditionally render data

Updated: January 18, 2024 By: Guest Contributor Post a comment

Introduction

Rendering data conditionally in a web application is a common need. With the combination of Express.js, a back-end web application framework for Node.js, and Handlebars, a templating engine, you can create dynamic views that respond to the data they receive. This tutorial aims to walk you through the process of using Handlebars within an Express app to conditionally render content.

Setting Up the Project

First, you need to have Node.js installed on your computer. Once you have Node.js set up, create a new directory for your project and initialize a new Node.js project within it by running npm init. After you answer the setup questions, you will have a new package.json file in your directory.

Install Express and express-handlebars by running:

npm install express express-handlebars

Create a new file named server.js – this will be your entry point.

Configuring Express to Use Handlebars

To configure Express to use Handlebars as its view engine, you need to require both Express and the express-handlebars library, and then set Handlebars as the view engine:

const express = require('express');
const { engine } = require('express-handlebars');

const app = express();

app.engine('handlebars', engine());
app.set('view engine', 'handlebars');
app.set('views', './views');

This tells Express where to find the views, and that they will be written in Handlebars template language. You’ll store your Handlebars templates in the views directory.

Creating Handlebars Templates

Create a new directory inside your project folder named views. This is where you’ll place your Handlebars templates. Create a file named index.handlebars within the views directory. This will be your main page.

Conditional Statements in Handlebars

Handlebars has its own built-in helpers, such as {{#if}}, {{#unless}}, {{#each}} etc., that you can use to render data conditionally.

{{#if condition}}
  <p>This will be rendered if the condition is true.</p>
{{/if}}

{{#unless condition}}
  <p>This will be rendered if the condition is false.</p>
{{/unless}}

For example, suppose you want to conditionally display a welcome message if the user is logged in.

{{#if loggedIn}}
  <h1>Welcome back, {{username}}!</h1>
{{else}}
  <h1>Welcome, guest!</h1>
{{/if}}

To make this work, your Express route would pass the context which includes the loggedIn and username properties.

app.get('/', (req, res) => {
  const user = {/* ... */};
  res.render('index', {
    loggedIn: user.isLoggedIn,
    username: user.name
  });
});

Using Helpers for Custom Conditions

Sometimes you may need to perform more complex logic in your templates. You can accomplish this by writing custom helpers. For example, you might want to check whether a number is odd or even:

const hbs = engine.create();
hbs.handlebars.registerHelper('isEven', function(value, options) {
  if ((value % 2) === 0) {
    return options.fn(this);
  } else {
    return options.inverse(this);
  }
});

app.engine('handlebars', hbs.engine);

And then use that helper in a template:

{{#isEven number}}
  <p>The number is even!</p>
{{else}}
  <p>The number is odd!</p>
{{/isEven}}

Combining Conditions

In Handlebars, you can also combine conditions using the and and or helpers which can be used in conjunction with {{#if}}.

{{#if (and loggedIn isAdmin)}}
  <h1>Welcome, admin {{username}}!</h1>
{{/if}}

Note: Handlebars does not include and or or helpers by default, so you will either need to write them yourself or include a library such as handlebars-helpers.

const helpers = require('handlebars-helpers')({
  handlebars: hbs.handlebars
});

// Use helpers as middleware
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');

Error Handling

Handlebars templates will fail silently if you try to render a variable that doesn’t exist. To make error handling easier, you might want to write a helper that throws an error when a required variable is missing:

hbs.handlebars.registerHelper('assert', function(value, message) {
  if (typeof value === 'undefined') {
    throw new Error(message);
  }
  return value;
});

Testing Your Application

Manually test your application to ensure that your conditional logic is working as expected. Automated testing might involve a testing framework like Mocha or Jest. Ensure you thoroughly test with different conditions to cover all the logical branches in your application.

Conditional rendering with Express and Handlebars allows you to build rich, interactive, and dynamic web applications. With custom helpers and built-in logic constructs, Handlebars provides the functionality required to make your templates as simple or complex as needed, depending on the data provided by your Express routes.

Wrapping Up

In this guide, we have covered the basics to get you started with conditional rendering using Express and Handlebars. Hopefully, this serves as a stepping stone to building more nuanced web applications with Node.js and to exploring more features of both Express and Handlebars.