Why does a semicolon in ejs template throws error - node.js

In the following code if the semicolon is removed the template engine does not throw error, else the error is thrown.
<ul>
<% for (i = 0; i < array.length; ++i) { %>
<%= JSON.stringify(array[i]); %>
<% } %>
</ul>
Although putting semicolon syntactically correct, why does the template engine throw error ?

As #torazaburo said, the contents between <=% and %> are an expression that gets parsed by ejs. However, think of it this way:
Your goal is to render the contents returned from JSON.stringify to the page right? So in that case, think of ejs expressions as implicitly calling .toString() on the result of the expression and then inserting that string into the page. By adding a semi-colon you've terminated the statement without assigning the returned value to anything.

Related

Unexpected token '/' in {FILE} while compiling ejs

I am working on this: https://www.youtube.com/watch?v=6FOq4cUdH8k
For some reason, the following line is causing the error in the title.
<% include ./partials/messages %>
Removing the line above solves the problem.
I have confirmed that it is not the messages file as there are no slashes in it.
<% if(typeof errors != 'undefined') { %>
<% errors.forEach(function(error){ %>
<%= error.msg %>
<% }); %>
<% } %>
as you can read in the official documentation
Includes are relative to the template with the include call. (This
requires the 'filename' option.) For example if you have
"./views/users.ejs" and "./views/user/show.ejs" you would use <%-
include('user/show'); %>.
You'll likely want to use the raw output tag (<%-) with your include
to avoid double-escaping the HTML output.
so instead of
<% include ./partials/messages %>
Write
<%- include ("./partials/messages") %>
Why?
Template tag <%- outputs the unescaped value into the template, whereas <% 'scriptlet' tag is used for control-flow, no output. The parenthesis and " " are used for filename location

Underscore Js _.each used with ejs error

I am trying to display the value in array using _.each and EJS dynamically. I am getting the values when i do it manually,but getting Unexpected token ; error while using _.each loop.
Here is the code
`<% _.each(pro,function(prof) { %>
alert(prof.Name);
<% } %>`
pro = {[object Object],[object Object]}
when i do it manually,i get the output.
i.e.
`<%= pro[0].Name %>`
Need help! Any other suggestions? Thanks
You seem have missed a parentheses here:
<% }) %>`
Beyond that, I'm not sure you can use underscore inside your EJS templates.
Try using a regular for.
<% for(var i=0; i<prof.length; i++) {%>
<li><%= prof[i] %></li>
<% } %>

How to convert ejs to jade?

I have troubles converting the following ejs to jade:
<% if (message.length > 0) { %>
<div class="alert alert-danger"><%= message %></div>
<% } %>
How does this block look in jade?
I'd write this as follows:
if message.length
.alert.alert-danger= message
... as message is a string, message.length evaluates to a falsy value (0) only if it's an empty string. I've also used buffered output here (note that = character) so that message value will be HTML escaped.
An alternative approach is comparing message with an empty string directly:
if message !== ''
.alert.alert-danger= message
Note that I dropped div in div.alert.alert-danger expression, as it's kind of default element for Jade templates. Have you used any other element, you'd have to start the expression with its tagname.
Try the following snippet
https://github.com/visionmedia/jade
- if(message.length>0){
div.alert.alert-danger #{message}
- }

Inside Express/EJS templates, what is cleanest way to loop through an array?

I have an Express.js app set up using EJS templates. I successfully looped through an array with classic JS syntax:
<% for (var i = 0; i < myArray.length; i++) {
this = myArray[i];
// display properties of this
} %>
But I'm wondering, is there a cleaner way to do this?
Specifically, can I use Underscore or Lodash to loop through with .each ? thank you
You can use forEach method
myArray.forEach(function(el, index) {
// el - current element, i - index
});
#wachme's answer is correct, but to stick with the original question, here is the version using Underscore's _.each (and integrated in template syntax):
<% _.each(myArray, function(el, index) { %>
Value is <%= el %>, index is <%= index %>.
<% }) %>
The advantage of Array.prototype.forEach is that you don't need to depend on Underscore in your templates. The advantage of _.each is that it has some additional tricks up its sleeves (for example, it also works on objects) and that it works in older JS environments without any need for polyfills.
As an aside, Underscore's _.template can be used instead of EJS, although it has fewer features. Also, the meaning of <%= and <%− is swapped between the two libraries. Naturally, you can always use _.each in Underscore templates.

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?
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.
most languages are like this:
irb
>> foo
NameError: undefined local variable or method `foo' for main:Object
from (irb):1
To check if test is defined, you need to do that:
<% if (this.test) { %>
here, test is defined
<% } %>

Resources