BorisMoore/jsrender — Issue #57: {{if}} {{#if} tags wrongly should wrap view.data as [view.data]
Author: fredyang
Created: 2011-12-27 20:07:40+00:00
State: open

I have a template, what I want is to test whether $data is null. If it is null, then don't render any markup. However, I found that the {{if}} has a bug, it use the following code to render in inner template.

return render( view.data, presenter.tmpl, view.ctx, view );

This is fine, if view.data itself is an object in an array, but it will render incorrectly, if it is an array. To fix this, we should use

return render( [view.data], presenter.tmpl, view.ctx, view );

Below is the code that I reproduce this bug, or check jsbin http://jsbin.com/efibup, or see my pull request.

<script type="text/html" id="mytmpl">
<h2>list</h2>
<ul>
{{#each $data}}
<li>{{=$data}}</li>
{{/each}}
</ul>
</script>

<script type="text/html" id="mytmpl2">
{{#each $data}}
<h2>list</h2>
<ul>
{{#each $data}}
<li>{{=$data}}</li>
{{/each}}
</ul>
{{/if}}
</script>

<script type="text/html" id="mytmpl3">
{{#if $data}}
<h2>list</h2>
<ul>
{{#each $data}}
<li>{{=$data}}</li>
{{/each}}
</ul>
{{/if}}
</script>

<h2>expected result</h2>

<p id="result"></p>
<hr>

<h2>{{#each}} result</h2>

<p id="result2"></p>
<hr>
<h2>{{#if}} incorrectly implemented as {{#each}}</h2>

<p id="result3"></p>
<hr>

<script>

var array = ["one", "two"];
var arrayAsObject = [ array ];

$( "#result" ).html(
$( "#mytmpl" ).render( arrayAsObject )
);

$( "#result2" ).html(
$( "#mytmpl2" ).render( arrayAsObject )
);

$( "#result3" ).html(
$( "#mytmpl3" ).render( arrayAsObject )
);

</script>