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.
It is possible to access JS variable in . ejs file. You just need to pass the JS object as second parameter of res. render() method.
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.
View engines allow us to render web pages using template files. These templates are filled with actual data and served to the client. There are multiple view engines, the most popular of which is Embedded Javascript (EJS).
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
Try prepending the variable with locals
Example: if(locals.user){}
<% if (locals.user) { %>
// Your logic goes here
<% } %>
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
To check if user is defined, you need to do that:
<% if (this.user) { %>
here, user is defined
<% } %>
I've come across the same issue using node.js with mongoose/express/ejs when making a relation between 2 collections together with mongoose's populate(), in this case admins.user_id existed but was related to an inexistant users._id.
So, couldn't find why:
if ( typeof users.user_id.name == 'undefined' ) ...
was failing with "Cannot read property 'name' of null" Then I noticed that I needed to do the checking like this:
if ( typeof users.user_id == 'undefined' ) ...
I needed to check the "container" of 'name', so it worked!
After that, this worked the same:
if ( !users.user_id ) ...
Hope it helps.
Came to this page for an answer but I came up with a shorter inline syntax for it which is:
<h2><%= user.name ? property.escrow.emailAddress : '' %></h2>
This may help somebody.
<p><%= locals?.message %></p>
or
<p><%= locals.message || '' %></p>
What I do is just pass a default object I call 'data' = '' and pass it to all my ejs templates. If you need to pass real data to ejs template, add them as property of the 'data' object.
This way, 'data' object is always defined and you never get undefined error message, even if property of 'data' exist in your ejs template but not in your node express route.
For your if
statement you need to use typeof
:
<% if (typeof user == 'object' && user) { %>
<% } %>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With