Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does EJS handle array.map(callback)?

Tags:

node.js

map

ejs

I am passing an array of objects to an EJS template, which I would like to map into links using the regular .map() method of arrays. But for reasons I can't figure out, the callback I'm passing to map() doesn't work within EJS the way I'd expect, and I'm getting empty results.

My data is an array of objects, each with a "section" and a "name" key. This array is passed as "entries" to the template:

siteHeaders = [ { section: "home", name: "Home"}, 
                { section: "about", name: "About Me"}, 
                ... plus few more ]

The template looks like this, and I have it in a local variable called (surprise) template:

<% entries = entries.map(function(elem) { -%>
  <% return -%>
  <a href="/<%= elem.section %>">
    <%= elem.name %>
  </a>
<% } ) -%>
<p><%- entries.join(" | ") %></p>

The result of this template, when I call require('ejs').render(template, {entries: siteHeaders}) is:

          <p> |  |  |  | </p>

What I don't get is why this doesn't work in an EJS template, when the corresponding map call works just fine in REPL:

> siteHeaders.map(function(e){ return '<a href="/' + e.section +'">' + e.name + '</a>' })
[ '<a href="/home">Home</a>',
  '<a href="/guide">About Me</a>',
  '<a href="/quickstart">Portfolio</a>',
  '<a href="/reference">Blog</a>',
  '<a href="/downloads">Contact</a>' ]
>

Any clues?

like image 351
Jason Black Avatar asked Nov 06 '12 22:11

Jason Black


People also ask

What is EJS used for?

EJS (Embedded JavaScript Templating) is one of the most popular template engines for JavaScript. As the name suggests, it lets us embed JavaScript code in a template language that is then used to generate HTML.

Is map a callback function?

The map() method calls a callback function on every element of an array and returns a new array that contains the results. The map() method takes two named arguments, the first one is required whereas the second one is optional.

Does EJS support forEach?

Looping Over Data in EJSTo loop over data, you can use . forEach .


2 Answers

This code should work:

<% entries = entries.map(function(elem) {
    return '<a href="/' + elem.section + '">' + elem.name + '</a>';
}) -%>
<p><%- entries.join(" | ") %></p>

You can't use simple html inside of functions. It's possible only in loops and conditions.

like image 162
Vadim Baryshev Avatar answered Sep 28 '22 07:09

Vadim Baryshev


It's not as clean as join(' | '), but if you don't want to concatenate, you can do this:

<% entries.forEach(function(entry, i, entries){ %>
    <a href="<%= entry.section %>"><%= entry.name %></a>
    <%= i == entries.length-1 ? ' | ' : '' %>
<% } %>
like image 42
chovy Avatar answered Sep 28 '22 06:09

chovy