Sling Academy
Home/Node.js/Express + Handlebars: How to Render JSON Data

Express + Handlebars: How to Render JSON Data

Last updated: January 18, 2024

Introduction

When developing web applications with Node.js, Express is often the go-to web framework for its flexibility and ease of use. Handlebars, on the other hand, is a popular templating engine that helps to dynamically create HTML pages on the server-side. In this tutorial, you will learn how to render JSON data using Express along with the Handlebars templating engine.

Setting Up Express and Handlebars

const express = require('express');
const exphbs = require('express-handlebars');
const app = express();

app.engine('handlebars', exphbs());
app.set('view engine', 'handlebars');

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

In this initial setup, we’ve created a simple Express server and set Handlebars as the default view engine. Ensure you have `express` and `express-handlebars` installed before you proceed.

Rendering JSON Data

Now let’s consider a case where you have some JSON data that you wish to display on a web page. Perhaps this data is fetched from an API or a database.

app.get('/', (req, res) => {
   const jsonData = {
    title: 'My JSON data',
    items: ['Item 1', 'Item 2', 'Item 3']
  };
res.render('home', jsonData);
});

We have defined the route ‘/’ that sends JSON data to the ‘home’ template. `res.render` is the Express function that passes data to Handlebars templates.

Creating a Handlebars Template

Next, let’s create a Handlebars view that will receive our JSON data.

<!DOCTYPE html>
<html>
<head>
  <title>{{title}}</title>
</head>
<body>
  <h1>{{title}}</h1>
  <ul>
    {{#each items}}
      <li>{{this}}</li>
    {{/each}}
  </ul>
</body>
</html>

This is a simple home.handlebars file within the ‘views’ directory. It loops through the ‘items’ array provided by our JSON data and displays each item in a list.

Fetching JSON Data from an External API

Sometimes you’ll want to fetch data from an external API instead of hardcoding it. For that, you’ll use a request library like ‘axios’.

const axios = require('axios');

app.get('/api-data', async (req, res) => {
  try {
    const response = await axios.get('https://api.example.com/data');
    res.render('apiView', { apiData: response.data });
  } catch (err) {
    res.status(500).send(err);
  }
});

In the snippet above, we’re using async/await to fetch data from an external API and then pass the response to a Handlebars template named ‘apiView’.

Displaying Nested JSON Data

Real-world JSON data is often more complex and nested. You need to adapt your Handlebars templates to handle this type of data.

{{#with apiData}}
  <h1>{{title}}</h1>
  {{#each categories}}
    <h2>{{this.name}}</h2>
    <ul>
      {{#each this.items}}
        <li>{{this.name}} - {{this.description}}</li>
      {{/each}}
    </ul>
  {{/each}}
{{/with}}

The `{{#with}}` helper scopes the block, making it easier to access nested properties. Similarly, `{{#each}}` can be nested to loop through arrays inside your JSON object.

Conclusion

By now, you should understand how to setup an Express server to render web pages using Handlebars, alongside incorporating JSON data into your views, both from hard-coded sources and external APIs. Remember that Handlebars provides a variety of helpers such as `{{#if}}`, `{{#unless}}`, `{{#with}}`, and `{{#each}}` to control the flow of your template rendering, which is especially useful when dealing with JSON data.

Keep in mind that as your project grows, organization becomes key. Split up your views into partials and use layouts to reuse code and keep your project maintainable. Make sure to also handle data fetching errors properly to avoid crashing your server.

That’s it for this tutorial. Happy coding!

Next Article: Node + Express + Mongoose: CRUD example (Rest API)

Previous Article: Writing Unit Tests in ExpressJS: A Developers’ Guide

Series: Node.js & Express Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates