adamb
adamb

Reputation: 4883

Render _.template using object w/ numeric keys

Ran into some weird behavior using underscore.js's template method:

var test = ['first', 'test'];
console.log(_.template('this is a <%= 1 %> ', test));

(Fiddle: http://jsfiddle.net/adamb/mbD6E/)

This snippets outputs: "this is a 1", while the expected result is "this is a test".

No errors are thrown. I've studied the source-code and there's no obvious explanation for this result. It's required that I use interpolation only in my template. I've tried converting the array explicitly to a collection using _.extend({}, test), but no dice.

How can I get this working?

Upvotes: 0

Views: 84

Answers (2)

benjaminbenben
benjaminbenben

Reputation: 1228

You can check the compiled template code with:

_.template('this is a <%= 1 %> ').source

which gives this function:

function(obj){
var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};
with(obj||{}){
__p+='this is a '+
( 1 )+
' ';
}
return __p;
}

the key part is:

with(obj){
  (1)
}

because 1 isn't a valid property/variable name, it doesn't try to match the properties of the object you are templating, so just prints out '1'.

if you were to use an object like {zero: 'first', one: 'test'} and a template of 'this is a <%= one %> ', then this would look like:

with(obj){
  (one)
}

which is kind of equivelant of obj.one

Upvotes: 3

Simon Boudrias
Simon Boudrias

Reputation: 44629

A number is not a valid javascript reference.

Here you probably want to write it this way: <%= this[1] %>.

If that's not working, then pass your array to an object key:

_.template('this is a <%= list[1] %> ', { list: test })

Upvotes: 1

Related Questions