This might seem a silly question but I can't seem to find the answer anywhere.
I'm hitting this Web API that returns an array of objects in JSON format:
Handlebars docs shows the following example:
<ul class="people_list">
{{#each people}}
<li>{{this}}</li>
{{/each}}
</ul>
In the context of:
{
people: [
"Yehuda Katz",
"Alan Johnson",
"Charles Jolley"
]
}
In my case I don't have a name for the array, it's just the root object of the response. I've tried using {{#each}}
with no luck.
First time using Handlebars... What am I missing?
UPDATE
Here's a simplified fiddle to show you what I'm asking: http://jsfiddle.net/KPCh4/2/
Does handlebars require the context variable to be an object and not an array?
This question is related to
arrays
loops
each
handlebars.js
I had a similar issue I was getting the entire object in this
but the value was displaying while doing #each
.
Solution: I re-structure my array of object like this:
let list = results.map((item)=>{
return { name:item.name, author:item.author }
});
and then in template file:
{{#each list}}
<tr>
<td>{{name }}</td>
<td>{{author}}</td>
</tr>
{{/each}}
Using this
and {{this}}
. See code below in node.js:
var Handlebars= require("handlebars");
var randomList= ["James Bond", "Dr. No", "Octopussy", "Goldeneye"];
var source= "<ul>{{#each this}}<li>{{this}}</li>{{/each}}</ul>";
var template= Handlebars.compile(source);
console.log(template(randomList));
Console log output:
<ul><li>James Bond</li><li>Dr. No</li><li>Octopussy</li><li>Goldeneye</li></ul>
I meant in the template()
call..
You just need to pass the results as an object. So instead of calling
var html = template(data);
do
var html = template({apidata: data});
and use {{#each apidata}}
in your template code
demo at http://jsfiddle.net/KPCh4/4/
(removed some leftover if
code that crashed)
Handlebars can use an array as the context. You can use .
as the root of the data. So you can loop through your array data with {{#each .}}
.
var data = [_x000D_
{_x000D_
Category: "General",_x000D_
DocumentList: [_x000D_
{_x000D_
DocumentName: "Document Name 1 - General",_x000D_
DocumentLocation: "Document Location 1 - General"_x000D_
},_x000D_
{_x000D_
DocumentName: "Document Name 2 - General",_x000D_
DocumentLocation: "Document Location 2 - General"_x000D_
}_x000D_
]_x000D_
},_x000D_
{_x000D_
Category: "Unit Documents",_x000D_
DocumentList: [_x000D_
{_x000D_
DocumentName: "Document Name 1 - Unit Documents",_x000D_
DocumentList: "Document Location 1 - Unit Documents"_x000D_
}_x000D_
]_x000D_
},_x000D_
{_x000D_
Category: "Minutes"_x000D_
}_x000D_
];_x000D_
_x000D_
$(function() {_x000D_
var source = $("#document-template").html();_x000D_
var template = Handlebars.compile(source);_x000D_
var html = template(data);_x000D_
$('#DocumentResults').html(html);_x000D_
});
_x000D_
.row {_x000D_
border: 1px solid red;_x000D_
}
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.0/handlebars.js"></script>_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>_x000D_
<div id="DocumentResults">pos</div>_x000D_
<script id="document-template" type="text/x-handlebars-template">_x000D_
<div>_x000D_
{{#each .}}_x000D_
<div class="row">_x000D_
<div class="col-md-12">_x000D_
<h2>{{Category}}</h2>_x000D_
{{#DocumentList}}_x000D_
<p>{{DocumentName}} at {{DocumentLocation}}</p>_x000D_
{{/DocumentList}}_x000D_
</div>_x000D_
</div>_x000D_
{{/each}}_x000D_
</div>_x000D_
</script>
_x000D_
This fiddle has both each
and direct json. http://jsfiddle.net/streethawk707/a9ssja22/.
Below are the two ways of iterating over array. One is with direct json passing and another is naming the json array while passing to content holder.
Eg1: The below example is directly calling json key (data) inside small_data variable.
In html use the below code:
<div id="small-content-placeholder"></div>
The below can be placed in header or body of html:
<script id="small-template" type="text/x-handlebars-template">
<table>
<thead>
<th>Username</th>
<th>email</th>
</thead>
<tbody>
{{#data}}
<tr>
<td>{{username}}
</td>
<td>{{email}}</td>
</tr>
{{/data}}
</tbody>
</table>
</script>
The below one is on document ready:
var small_source = $("#small-template").html();
var small_template = Handlebars.compile(small_source);
The below is the json:
var small_data = {
data: [
{username: "alan1", firstName: "Alan", lastName: "Johnson", email: "[email protected]" },
{username: "alan2", firstName: "Alan", lastName: "Johnson", email: "[email protected]" }
]
};
Finally attach the json to content holder:
$("#small-content-placeholder").html(small_template(small_data));
Eg2: Iteration using each.
Consider the below json.
var big_data = [
{
name: "users1",
details: [
{username: "alan1", firstName: "Alan", lastName: "Johnson", email: "[email protected]" },
{username: "allison1", firstName: "Allison", lastName: "House", email: "[email protected]" },
{username: "ryan1", firstName: "Ryan", lastName: "Carson", email: "[email protected]" }
]
},
{
name: "users2",
details: [
{username: "alan2", firstName: "Alan", lastName: "Johnson", email: "[email protected]" },
{username: "allison2", firstName: "Allison", lastName: "House", email: "[email protected]" },
{username: "ryan2", firstName: "Ryan", lastName: "Carson", email: "[email protected]" }
]
}
];
While passing the json to content holder just name it in this way:
$("#big-content-placeholder").html(big_template({big_data:big_data}));
And the template looks like :
<script id="big-template" type="text/x-handlebars-template">
<table>
<thead>
<th>Username</th>
<th>email</th>
</thead>
<tbody>
{{#each big_data}}
<tr>
<td>{{name}}
<ul>
{{#details}}
<li>{{username}}</li>
<li>{{email}}</li>
{{/details}}
</ul>
</td>
<td>{{email}}</td>
</tr>
{{/each}}
</tbody>
</table>
</script>
Source: Stackoverflow.com