249

I'm using the underscore.js templating function and have done a template like this:

<script type="text/template" id="gridItem">
    <div class="griditem <%= gridType %> <%= gridSize %>">
        <img src="<%= image %>" />
        <div class="content">
            <span class="subheading"><%= categoryName %></span>
            <% if (date) { %><span class="date"><%= date %></span><% }  %>
            <h2><%= title %></h2>
        </div>
    </div>
</script>

As you can see I have an if statement in there because all of my models won't have the date parameter. However this way of doing it gives me an error date is not defined. So, how can I do if statements within a template?

8 Answers 8

461

This should do the trick:

<% if (typeof(date) !== "undefined") { %>
    <span class="date"><%= date %></span>
<% } %>

Remember that in underscore.js templates if and for are just standard javascript syntax wrapped in <% %> tags.

6
  • 2
    Works great, and just discovered that JS switch/case statements work nicely in template markup, too.
    – nickb
    Commented Nov 9, 2011 at 2:45
  • Awesome answer. Can you please also tell how can I use alternating classes when I am using templates? Like first <li> should get class a and next b? Commented Nov 23, 2011 at 7:18
  • 4
    @BlackDivine I know it's kind of late, but for alternating styles you should use :nth-child(even) and :nth-child(odd) CSS selectors, not change your template.
    – user490524
    Commented Aug 30, 2013 at 8:41
  • its looking same as java scriptlets used for rendering variables in jsp Commented Sep 5, 2013 at 4:34
  • I ended up with this line at the end {{ } }}, because I had to change the <% %> wrapper and it still worked.
    – Nosebleed
    Commented Feb 5, 2015 at 12:24
80

If you prefer shorter if else statement, you can use this shorthand:

<%= typeof(id)!== 'undefined' ?  id : '' %>

It means display the id if is valid and blank if it wasn't.

2
  • 4
    Conditional operator, which gets the nickname "ternary" since it's the only common ternary operator (three-operands).
    – Keen
    Commented Oct 21, 2014 at 20:17
  • 1
    Note that an occasional shortcoming of the technique proposed in this answer is that you're stuck doing string interpolation all over again, which templates are supposed to solve for you. As of right now, _.template inserts a ; at the start of each compiled code tag. Thus, it can handle tags breaking between statements, but not inside of expressions. Compare;if(a){b;}else{c;} to ;a?b;:c;.
    – Keen
    Commented Oct 21, 2014 at 20:19
21

Depending on the situation and or your style, you might also wanna use print inside your <% %> tags, as it allows for direct output. Like:

<% if (typeof(id) != "undefined") {
     print(id);
}
else {
    print('new Model');
} %>

And for the original snippet with some concatenation:

<% if (typeof(date) != "undefined") {
    print('<span class="date">' + date + '</span>');
} %>
0
10

Here is a simple if/else check in underscore.js, if you need to include a null check.

<div class="editor-label">
    <label>First Name : </label>
</div>
<div class="editor-field">
    <% if(FirstName == null) { %>
        <input type="text" id="txtFirstName" value="" />
    <% } else { %>
        <input type="text" id="txtFirstName" value="<%=FirstName%>" />
    <% } %>
</div>
3
  • 1
    null is not the same as undefined, it would still produce an error
    – xorinzor
    Commented Apr 2, 2013 at 17:45
  • 4
    In this case it wouldn't matter, since he checks the value using ==, which will convert the value. Because of the type-conversion the following statement is true: null == undefined - Not endorsing that, just saying. Commented Oct 26, 2013 at 17:39
  • I think it's better to use _.isEmpty() Commented Feb 5, 2016 at 4:20
6

Responding to blackdivine above (about how to stripe one's results), you may have already found your answer (if so, shame on you for not sharing!), but the easiest way of doing so is by using the modulus operator. say, for example, you're working in a for loop:

<% for(i=0, l=myLongArray.length; i<l; ++i) { %>
...
<% } %>

Within that loop, simply check the value of your index (i, in my case):

<% if(i%2) { %>class="odd"<% } else { %>class="even" <% }%>

Doing this will check the remainder of my index divided by two (toggling between 1 and 0 for each index row).

3

You can try _.isUndefined

<% if (!_.isUndefined(date)) { %><span class="date"><%= date %></span><% } %>
1
  • Beware the difference between "date is undefined" and "date is not defined". They should have called that error "No variable or global property exists with the name 'date'." The code you've proposed will still throw an exception if date doesn't exist at all. You really do need the typeof in this case, although it would be even better to use a named variable when we're duck-typing template data.
    – Keen
    Commented Oct 21, 2014 at 20:25
1

From here:

"You can also refer to the properties of the data object via that object, instead of accessing them as variables." Meaning that for OP's case this will work (with a significantly smaller change than other possible solutions):

<% if (obj.date) { %><span class="date"><%= date %></span><% }  %>
0

To check for null values you could use _.isNull from official documentation

isNull_.isNull(object)

Returns true if the value of object is null.

_.isNull(null);
=> true
_.isNull(undefined);
=> false

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.