web #node.js #handlebars

Looping Over An Array with Handlebars

Jan 6 '19 · 2 min read · 2076

Using handlebars' built-in helper methods to loop over an array of data in your template.hbs file.

Intro

O

ften, when using any templating language, you will have an array of data and want to display it as a list of successive elements, where the HTML structure may be the same and only the data needs to change. This is exactly the case for this blog when displaying the list of latest posts. A call to the database returns an array of post objects. The HTML structure of each post preview is the same, only the title, date, thumbnail etc. are swapped out.

I think most popular templating languages these days, like handlebars and pug, support iterating over an array with their own built-in conditional logic and helper functions. Being able to generate markup by iteration keeps your templates lean, maintainable, etc. etc... all that good stuff.

Handlebars

The example I am going to use for the rest of this post is generating a list of todos, each with a text body and completion flag. In Node.js, your JSON data is most likely going to be the result of a database query. The returned data might look like something below:

todos = [{
  "text": "Email back head office",
  "completed": false
}, {
  "text": "Start training for 5K run",
  "completed": false 
}, {
  "text": "Walk the dog",
  "completed": true
}]

Using this data, we want to use handlebars to render the following HTML:

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <ol>
      <li>Email back head office</li>
      <li>Start training for 5K run</li>
      <li>Walk the dog (Completed)</li>
    </ol>
  </body>
</html>

For this, handlebars has a bult-in 'each' helper. The small example below is used on this blog for rendering the array of tags associated with each individual post. You can see that the helper takes an array of tags called tag, where tag is a property on a JSON object representing a single post - which itself might be part of an array of post objects. Then to access each tag element in the array, you use the 'this' keyword.

{{#each tag}}
<a href="tags/{{this}}">#{{this}}</a>
{{/each}}

Now we know how it works, we can apply this to our todo example. Try and have a go at doing this yourself first, and then look at the template solution below to see if you got it right - you shouldn't find it too difficult.

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <ol>
      {{#each todos}}
      <li>{{this.text}}{{#if this.completed}} (Completed){{/if}}</li>
      {{/each}}
    </ol>
  </body>
</html>

In Node.js with the Express.js framework, when you have set up handlebars as your templating engine, you render this using:

res.render('mytemplate.hbs', {todos});