I have this code:
_.templateSettings = {interpolate : /\{\{(.+?)\}\}/g};
var _d = _.template($('#_d').html());
$.get('/foo', function(data) {
$('#output').html(_d(data));
});
and in HTML:
<div id="_d">
{{name}} {{phone}}
</div>
<div id="output"></div>
/foo
returns something like {"name":"joe","phone":"12345"}
, but sometimes it doesn't have phone
thus simply returns {"name":"joe"}
, which will choke template evaluation thus nothing gets printed in output
. How do I make a variable optional?
EDIT: /foo
is beyond my control
I have this code:
_.templateSettings = {interpolate : /\{\{(.+?)\}\}/g};
var _d = _.template($('#_d').html());
$.get('/foo', function(data) {
$('#output').html(_d(data));
});
and in HTML:
<div id="_d">
{{name}} {{phone}}
</div>
<div id="output"></div>
/foo
returns something like {"name":"joe","phone":"12345"}
, but sometimes it doesn't have phone
thus simply returns {"name":"joe"}
, which will choke template evaluation thus nothing gets printed in output
. How do I make a variable optional?
EDIT: /foo
is beyond my control
6 Answers
Reset to default 7The ||
operator is useful for this sort of thing:
$.get('/foo', function(data) {
data.phone = data.phone || "";
$('#output').html(_d(data));
});
But since you're already using Underscore, you can use the _.defaults
function. This approach is particularly useful for providing defaults for multiple fields:
$.get('/foo', function(data) {
_.defaults(data, {name : 'joe', phone : ''});
$('#output').html(_d(data));
});
I liked @namuol solution, another thing that we could do is set the defaults hash at the model extends
var MyModel = Backbone.Model.extend({
defaults: {
"foo": "I",
"bar": "love",
"yeah": "sara"
}
});
Just another option.
You can have an html
<div id="d">
{{data.name}} {{data.phone}}
</div>
Use the template as below to avoid undefined variable issue for phone
_.templateSettings = {
interpolate : /\{\{(.+?)\}\}/g
};
var template = _.template($('#d').html());
var jsonResponse = {"name":"Jeo"}; // phone is missing
var result = template({"data":jsonResponse});
A practical solution would be to include phone
in the object, but with an empty value:
{"name":"joe","phone":""}
There are some good answers above, but you can use _.partial
to get a single function that applies a template with defaults:
foobarTemplate = _.template('<%=foo%><%=bar%>')
barPrefilled = _.partial(_.defaults, _, {bar:'def'})
foobarTemplate(barPrefilled({foo:'abc'}))
// "abcdef"
foobarTemplateWithDefaults = function (data) {return foobarTemplate(barPrefilled(data));}
foobarTemplateWithDefaults({foo:'wat'})
// "watdef"
foobarTemplateWithDefaults({foo:'foo', bar:'bar'})
// "foobar"
And then there is the obvious: Put this in the top of your template:
<%
if (typeof(phone) === "undefined") {
phone = "";
}
%>
Working snippet:
$(function() {
$('#result').html(
_.template(
$('#template').html(), {
interpolate: /\{\{(.+?)\}\}/g
}
)({
foo: 23,
// No value for bar
// bar: 11,
},)
)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="x-template" id="template">
<%
if (typeof(bar) === "undefined") {
bar = "default";
}
%>
This is {{ foo }} and {{ bar }}
</script>
<div id="result"></div>
(also as jsfiddle)