ejs icon indicating copy to clipboard operation
ejs copied to clipboard

Node ejs Sort Filter - Syntax or Problem?

Open Digital-Thor opened this issue 11 years ago • 1 comments

I've followed the EJS tutorial by Chad Lung and it worked fine for simple filters like upcase, downcase and first, but when I changed the filter to sort, I got a runtime type error on line 5 below.

Does anyone know if the sort filter works in EJS or have I misunderstood the syntax?

3| <ul>
4|   <% messages.forEach(function(msgObj){ %>
5|     <li><%=: msgObj.name | sort %> says: <%= msgObj.message %></li>
6|   <% }) %>
7| </ul>
8| <% include footer.html %>

TypeError: /home/thor/ejs-sort/views/index.ejs:5

Object prototype may only be an Object or null at Function.create (native) at Object.exports.sort (/home/thor/ejs-sort/node_modules/ejs/lib/filters.js:54:17) at buf.push. </ul> .buf (eval at (/home/thor/ejs-sort/node_modules/ejs/lib/ejs.js:236:14), :31:196) at Array.forEach (native) at eval (eval at (/home/thor/ejs-sort/node_modules/ejs/lib/ejs.js:236:14), :31:110) at eval (eval at (/home/thor/ejs-sort/node_modules/ejs/lib/ejs.js:236:14), :33:37) at /home/thor/ejs-sort/node_modules/ejs/lib/ejs.js:249:15 at Object.exports.render (/home/thor/ejs-sort/node_modules/ejs/lib/ejs.js:287:13) at View.exports.renderFile as engine (/home/thor/ejs-sort/node_modules/ejs/lib/ejs.js:317:20) at View.render (/home/thor/ejs-sort/node_modules/express/lib/view.js:76:8)

Digital-Thor avatar Aug 20 '13 01:08 Digital-Thor

The sort and sort_by:'prop' filters seem to be for rendering a single concatenated value, not for looping and rendering each item with additional markup.

Here are a few examples.

{ names: ['foo','bar','baz'] } 

Template: <p> <%=: names %> </p> Output: <p> foo,bar,baz </p>

Template: <p> <%=: names | sort %> </p> Output: <p> bar,baz,foo </p>

A more complex array containing objects can be sorted, but still only outputs a single concatenated value.

{ users: [
    {id: 2, name: 'foo'},
    {id: 3, name: 'bar'},
    {id: 1, name: 'baz'},
  ]
}

Template: <p> <%=: users %> </p> Output: <p> [object Object],[object Object],[object Object] </p>

Template: <p> <%=: users | map:'name' %> </p> Output: <p> foo,bar,baz </p>

Template: <p> <%=: users | sort_by:'id' | map:'name' %> </p> Output: <p> baz,foo,bar </p>

It looks like the error you got was caused by trying to sort the name value itself, which is probably a string and is not sortable (hence "..may only be an Object..").

I would recommend doing the sorting before sending data to EJS.

mrmoses avatar Mar 18 '14 02:03 mrmoses