49

What is the best way to check for an undefined property in an ejs template?

(I'm using the node.js package by TJ Holowaychuk)

Example:

var tpl = '<% if (foo) { %>foo defined<% } else { %>foo undefined<% } %>';
console.log(ejs.render(tpl, { locals: { bar: "baz" } }));

I'd expect this to render "foo undefined". It does throw an foo undefined error instead.

I know that this is not supposed to be an issue, since this is expected behavior in the tests. Is there an easy way to avoid this?

The only solution I found is using the hasOwnProperty method.

var tpl = '<% if (hasOwnProperty("foo")) { %>foo defined<% } else { %>foo undefined<% } %>';
console.log(ejs.render(tpl, { locals: { bar: "baz"} }));

This doesn't throw any errors.

Is there a better way to keep the template clean? Or why does it throw this error?

pvorb
  • 7,157
  • 7
  • 47
  • 74

4 Answers4

77

Another way to test for a property is to reference it indirectly via the locals object. Using your example:

var tpl = '<% if(locals.foo){ %>foo defined<% }else{ %>foo undefined<% } %>';
console.log(ejs.render(tpl, { locals: { bar: "baz"} }));
Richard Marr
  • 3,044
  • 1
  • 22
  • 31
33

I would use typeof, as in if (typeof foo == 'undefined'). I use the typeof operator with the string "undefined", whereas some people might do a direct comparison with the undefined global variable. I prefer this method because it is protected against some terrorist JS library developer changing the value of the global variable, leaving your code broken.

This could also be expressed as a ternary, which some view as "cleaner" due to the absence of curlies:

var tpl = '<% (typeof foo != "undefined" ? %>foo defined<% : %>foo undefined<% ) %>';
Chris Baker
  • 49,926
  • 12
  • 96
  • 115
  • 2
    This works and maybe it's the formally correct one. But I personally don't like it, since it's too long for my templates. – pvorb Sep 09 '11 at 12:06
  • 1
    Note that this is the only method that will work with client side EJS templates. The other methods rely on checking the `res` object which will not exist with client side templates. – dbasch Dec 02 '14 at 19:14
16

Simplest, and cleanest in my opinion:

<%= (!!locals.foo)?foo:'' %>

rob_james
  • 1,262
  • 1
  • 12
  • 17
3

Earlier version of EJS supports only locals But Now in the latest versions of EJS support res.locals

Sample with ternary operator -

<%= (res.locals.foo)?"foo":"" %>

Sample with if-else -

<% if (res.locals.urvariable) { %>
   <h1><%= urvariable.value1 %></h1> 
<% } else { %> 
   <h1><%= urvariable.value2 %></h1> 
<% } %>
Subhradip D.
  • 51
  • 1
  • 7