Costa Michailidis
Costa Michailidis

Reputation: 8178

Express, EJS, challenge with testing for undefined

I'm creating a simple website with nodejs using the express framework, couchdb for a database and EJS for templating. There will be times when some of my fields are null or undefined in some of my JSON docs, and I need to handle that.

<% if (typeof test !== 'undefined') { %>
  <p><%= test %></p>
<% } %>

That bit of code seems to handle the 'test' field being undefined just fine, but the code below throws an error that says 'test is undefined'

<% if (test) { %>
  <p><%= test %></p>
<% } %>

Why doesn't javascript understand test to be undefined and then just put false in the if clause?

Upvotes: 1

Views: 6788

Answers (3)

HenioJR
HenioJR

Reputation: 634

To check if test is defined, you need to do that:

<% if (this.test) { %>
   here, test is defined
<% } %>

Upvotes: 2

maerics
maerics

Reputation: 156444

Because the concept of "undefined" is different than the state of a variable being defined in the JavaScript language. The reasons for this are understandable but the effects can be confusing, especially regarding variable names vs object properties.

You have demonstrated how trying to access an undefined variable will throw an exception. Don't confuse this state (a variable is not defined) with the "undefined" type:

if (bogusVariable) { // throws ReferenceError: bogusVariable is not defined.
typeof(bogusVariable); // => undefined - wow, that's confusing.

However, properties of objects which are not defined can be tested safely:

var x = {}; // an object
x.foo; // => undefined - since "x" has no property "foo".
typeof(x.foo); // => undefined
if (!x.foo) { /* true */ }

You could take advantage of this property by noting that all variables are actually properties of the "global" object (either "global" or "window", in web browsers).

bogus; // => ReferenceError: bogus is not defined.
global.bogus; // => undefined (on node/rhino)
window.bogus; // => undefined (on web browsers)

So you might be able to write your EJS code as such:

<% if (global.test) { %>
  <p><%= test %></p>
<% } %>

Yes, it's confusing, as are many parts of the JavaScript language.

Upvotes: 9

TJ Holowaychuk
TJ Holowaychuk

Reputation: 261

most languages are like this:

  irb
  >> foo
  NameError: undefined local variable or method `foo' for main:Object
        from (irb):1

Upvotes: 4

Related Questions