What is the proper way to check for existence of variable in an EJS template (using ExpressJS)?
On the EJS github page, there is one and only one simple example: https://github.com/visionmedia/ejs
Example
<% if (user) { %>
<h2><%= user.name %></h2>
<% } %>
This seems to be checking for the existence of a variable named user, and if it exists, do some stuff. Duh, right?
My question is, why in the world would Node throw a ReferenceError if the user variable doesn't exist? This renders the above example useless. What's the appropriate way to check for the existence of a variable? Am I expected to use a try/catch mechanism and grab that ReferenceError?
ReferenceError: user is not defined
at IncomingMessage.anonymous (eval at <anonymous> (/usr/local/lib/node/.npm/ejs/0.3.1/package/lib/ejs.js:140:12))
at IncomingMessage.<anonymous> (/usr/local/lib/node/.npm/ejs/0.3.1/package/lib/ejs.js:142:15)
at Object.render (/usr/local/lib/node/.npm/ejs/0.3.1/package/lib/ejs.js:177:13)
at ServerResponse.render (/usr/local/lib/node/.npm/express/1.0.7/package/lib/express/view.js:334:22)
at Object.<anonymous> (/Users/me/Dropbox/Projects/myproject/server.js:188:9)
at param (/usr/local/lib/node/.npm/connect/0.5.10/package/lib/connect/middleware/router.js:146:21)
at pass (/usr/local/lib/node/.npm/connect/0.5.10/package/lib/connect/middleware/router.js:162:10)
at /usr/local/lib/node/.npm/connect/0.5.10/package/lib/connect/middleware/router.js:152:27
at Object.restrict (/Users/me/Dropbox/Projects/myproject/server.js:94:5)
at param (/usr/local/lib/node/.npm/connect/0.5.10/package/lib/connect/middleware/router.js:146:21)
I understand that I could make this error go away by simply adding a "user" local variable in my server code, but the whole point here is that I want to check for the existence of such variables at runtime using your every day if/else nullcheck type pattern. An exception for a variable that doesn't exist seems ridiculous to me.
Solution 1:
The same way you would do it with anything in js, typeof foo == 'undefined'
, or since "locals" is the name of the object containing them, you can do if (locals.foo)
. It's just raw js :p
Solution 2:
Try prepending the variable with locals
Example: if(locals.user){}
Solution 3:
<% if (locals.user) { %>
// Your logic goes here
<% } %>
Solution 4:
You can create a view helper which checks for "obj === void 0", this one is for express.js:
res.locals.get = function() {
var args = Array.prototype.slice.call(arguments, 0);
var path = args[0].split('.');
var root = this;
for (var i = 0; i < path.length; i++) {
if(root[path[i]] === void 0) {
return args[1]?args[1]:null;
} else {
root = root[path[i]];
}
};
return root;
}
Then use it in the view like
<%- get('deep.nested.non.existent.value') %> //returns: null
<%- get('deep.nested.non.existent.value', "default value") %> //returns: default value