I'm having a problem with Underscore.js templates and Internet Explorer. Here's part of the template which is causing trouble:
<p>
<% if ( typeof description !== 'undefined' ) { %>
<%- description %>
<% } else { %>
No description
<% } %>
</p>
When the variable description
is undefined (which means I'm not supplying it to the template at all, the variable does not exist), this works just fine in Safari, Firefox, Chrome.
Internet Explorer however, doesn't work correctly. Instead of showing No description
IE8 and IE9 show [object HTMLMetaElement]
, and IE7 shows [object]
.
Checking the result of typeof description
returns undefined
in Safari, Firefox, Chrome, but apparently Internet Explorer returns object
instead.
I already tried Underscore.js's _.isUndefined(value)
function, but that one doesn't work when the variable does not exist.
Does anyone know a workaround for this problem? (note that I am unable to supply the variable with no value - it either exists, or it doesn't)
Update I found a workaround in one of the Underscore.js Github issues https://github.com/documentcloud/underscore/issues/237#issuecomment-1781951
Can someone explain why IE behaves differently, and why the workaround actually works?
Update 2 @John-DavidDalton has provided another, better workaround in the comments below (linking directly to it doesn't seem to work)
If you
typeof something
and the something isnull
,object
is returned. Try checking for null after checking for'undefined'
.From the fine manual:
You can see what's going on using the compiled template's
source
property:gives you (tweaked for clarity):
The
with
is the source of your problem:So given this:
JavaScript will first look for
obj.pancakes
and if there is nopancakes
property inobj
, it will look forpancakes
in the global scope. Apparently IE has awindow.description
value which represents one of the page's<meta>
tags. Using your own namespace inside the template (as in the work-around) sort of negates whatwith
does and keeps you from getting to the globalwindow
properties.