Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better handling of null values in Mustache sections. #307

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 30 additions & 30 deletions view/mustache/mustache.js
Original file line number Diff line number Diff line change
Expand Up @@ -643,34 +643,34 @@ function( can ){
}

// Otherwise interpolate like normal.
if (valid) {
switch (mode) {
// Truthy section.
case '#':
// Iterate over arrays
if (isArrayLike(name)) {
for (i = 0; i < name.length; i++) {
result.push(options.fn.call(name[i] || {}, context) || '');
}
return result.join('');
}
// Normal case.
else {
return options.fn.call(name || {}, context) || '';
switch (true) {
// Truthy section.
case mode === '#' && valid:
case mode === '^' && !valid:
// Iterate over arrays
if (isArrayLike(name)) {
for (i = 0; i < name.length; i++) {
result.push(options.fn.call(name[i] || {}, context) || '');
}
break;
// Falsey section.
case '^':
return options.inverse.call(name || {}, context) || '';
break;
default:
// Add + '' to convert things like numbers to strings.
// This can cause issues if you are trying to
// eval on the length but this is the more
// common case.
return '' + (name !== undefined ? name : '');
break;
}
return result.join('');
}
// Normal case.
else {
return options.fn.call(name || {}, context) || '';
}
break;
// Falsey section.
case mode === '#' && !valid:
case mode === '^' && valid:
return options.inverse.call(name || {}, context) || '';
break;
case valid:
// Add + '' to convert things like numbers to strings.
// This can cause issues if you are trying to
// eval on the length but this is the more
// common case.
return '' + (name !== undefined ? name : '');
break;
}

return '';
Expand Down Expand Up @@ -745,10 +745,10 @@ function( can ){
value = contexts[i];

// Make sure the context isn't a failed object before diving into it.
if (value !== undefined) {
if (typeof value !== 'undefined' && value !== null) {
for (j = 0; j < namesLength; j++) {
// Keep running up the tree while there are matches.
if (typeof value[names[j]] != 'undefined') {
if (typeof value[names[j]] !== 'undefined' && value[names[j]] !== null) {
lastValue = value;
value = value[name = names[j]];
}
Expand Down Expand Up @@ -791,7 +791,7 @@ function( can ){
return defaultObserve.attr(defaultObserveName);
}
// Support helper-like functions as anonymous helpers
if (obj !== undefined && can.isFunction(obj[ref])) {
if (typeof obj !== 'undefined' && obj !== null && can.isFunction(obj[ref])) {
return obj[ref];
}
// Support helpers without arguments, but only if there wasn't a matching data reference.
Expand Down
22 changes: 22 additions & 0 deletions view/mustache/test/mustache_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1280,4 +1280,26 @@ test("Rendering models in tables produces different results than an equivalent o
equal(elements.length, 1, 'Only one <tbody> rendered');
})

test("Null properties do not throw errors in Mustache.get", function() {
var renderer = can.view.mustache("Foo bar {{#foo.bar}}exists{{else}}does not exist{{/foo.bar}}")
, div = document.createElement('div')
, div2 = document.createElement('div')
, frag, frag2;

try {
frag = renderer(new can.Observe({
foo : null
}))
} catch(e) {
ok(false, "rendering with null threw an error");
}
frag2 = renderer(new can.Observe({
foo : {bar : "baz"}
}))
div.appendChild(frag);
div2.appendChild(frag2);
equal(div.innerHTML, "Foo bar does not exist");
equal(div2.innerHTML, "Foo bar exists");
})

});