Handling “variable is not defined” with underscore template engine

One of the cool thing with backbone.js is that you can plug in about any javascript templating engine there is. Also another nice extra is that there is one already bundled with underscore.js that is quite powerful.

Personally the template engine provided with underscore cover most of my use cases and is enough for me, but there is one thing that I have found very unpleasant, you cannot pass undefined keys to it. Here an example:

var template =_.template($("#titlebar_tpl").html());
var data = {"title":"Planning"};
 
$(body).append(template(data));
<script id="titlebar_tpl" type="text/template">
<input id="<%= id %>">
<span class="title"><%= title %></span>
</script>

There you go, in this example id will be undefined and will throw a js error, that is quite an hassle when you handle dynamic templates that might not always have all the data asked in the template.

Fortunately, there is an easy fix

While direct properties will throw an error, wrapping this in another object will do the trick. Here an example:

// Old way
var data = {"title":"Planning"};
// New way
var data = {"data": {"title":"Planning"}};
<script id="titlebar_tpl" type="text/template">
<input id="<%= data.id %>">
<span class="title"><%= data.title %></span>
</script>

Slightly painful code wise, but still a nice solution without headache. Another nice touch, you do not even have to check if the property exist, it will not show as undefined but just not show at all (You can of course check if it exists to add code logic in your template).

There you go!

Cedric Dugas is a front-end veteran with more than 9 years under the belt, between his open source projects & entrepreneurial ambitions he is a product architect at CakeMail. Why don't you follow him on twitter.

17 Comments on "Handling “variable is not defined” with underscore template engine"

  1. It's even easier as the template function internally uses obj so you could write obj.id

  2. Ondra says:

    But this might change in the future …

  3. Igor says:

    Any ideas why this might happen? Maybe it’s because it’s evaled?
    As I can see using the template source, if you process a template with the following construct:

    something

    The if construct turns into a simple “if (id)”. This has to work with undefined variables, or am I missing something?

  4. Nathan says:

    Nice. I was looking for this solution (great that this was the first page I read).

    Even better, I realise that this enables us to do simple namespacing in our templates, which was something that I just realised I needed 5 mins before reading your article, but didn’t know how I was going to cleanly get around it.

    Now I do! Thanks! :)

  5. Eka says:

    I have also tried _.isUndefined(title), but it doesn’t work either.
    but your solution just work.
    Thank you

  6. Ben says:

    I’ve found a couple things to be helpful. What you outlined above is really good, especially if you expand on it a bit: { data: model.toJson(), permissions: somePermObject, state: someStateObject }. State and permissions can be useful bits of data for a view that can be kept out of the model.

    Also, in a less pleasant way, you can check a variable like this:

    {{ if(null != someVar) { }}
    // do stuff
    {{ } //end if }}

    null != will work without crashing an underscore template.

  7. micrddrgn says:

    Or you can just set

    _.templateSettings.variable = ‘data’;

    and all your data will available through “data.variable” not only in this but in all templates

  8. Joe says:

    Not necessary guys, check the underscore source code, the “obj” is already there, just write like this and you will be golden.

    <input id="”>

  9. Allen says:

    If i my json obj has 10 fields, i have chosen 3 fields(which may differ each time depends upon the user selection) and i wanna render it as a table, how am i supposed to give . any idea???

  10. alex says:

    Brilliant!!! Thank you.

  11. Geo says:

    Thank you so much! This really improved my quality of life.

  12. What’s up to every single one, it’s really a good
    for me to go to see this website, it consists of priceless Information.

    Here is my webpage: locked file folders on iphone

Got something to say? Go for it!