Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

checking for undefined variable in underscore template

I show a modal view of libraryPrep objects in my template like this:

if (_.isUndefined(this.libraryPreps)) {
                this.$el.html(this.template({  }));
            } else {
                this.$el.html(this.template({ libraryPreps: this.libraryPreps.toJSON() }));
            }

The else statement works when I have a libraryPreps object. In my template, I use it like this:

<select id="libraryPreps" >
                    <%  if (!_.isUndefined(libraryPreps)) { %>
                    <% _.each(libraryPreps, function (libraryPrep) { %>
                    <option value="<%=libraryPrep.id%>"><%= libraryPrep.name %></option>
                    <% }); %>
                    <% } %>
                </select>

When I don't have a libraryPreps object, I don't get my template to render and I get an error on the console that libraryPreps is undefined. Am I checking for undefined incorrectly in my template? I feel like I'm checking it the same way in my backbone modal view, but for some reason, in my actual template, it doesn't seem to work. Is my template notation correct? Thanks.

like image 300
Crystal Avatar asked Jun 07 '13 05:06

Crystal


1 Answers

If you're passing the variable to a function, it is getting evaluated and will throw an error as there is no such variable. In your backbone view, in contrast, you're accessing a property of an object which will always work (and return the undefined value if no property with that name exists).

Instead, you will have to use the typeof operator on it, that will even work for undeclared variables (have a look at variable === undefined vs. typeof variable === "undefined" and JavaScript check if variable exists (is defined/initialized)):

<select id="libraryPreps"><%
    if (typeof libraryPreps !== "undefined") {
        _.each(libraryPreps, function (libraryPrep) { %>
            <option value="<%=libraryPrep.id%>"><%= libraryPrep.name %></option><%
        });
    }
%></select>

To use _.isUndefined in your template, you'd need to make the value explicitly available in the template. From the docs:

By default, template places the values from your data in the local scope via the with statement. However, you can specify a single variable name with the variable setting. This can significantly improve the speed at which a template is able to render.

_.template("Using 'with': <%= data.answer %>", {answer: 'no'}, {variable: 'data'});
=> "Using 'with': no"

So with that, you can write templates like this:

 <% if (!_.isUndefined(data.libraryPreps)) { %> …
 <% if ("libraryPreps" in data) { %> …
like image 193
Bergi Avatar answered Sep 23 '22 13:09

Bergi