I am brand new at this Javascript/JSON/Handlebars thing, and I am having trouble getting a JSON object, with two nested levels, to work in a Handlebars template.
I hav
There are a couple of changes to suggest, first you shouldn't write an object with several keys { Chapter:, Chapter:, etc...}
The other suggestion is to review the way Handlebars works, it doesn't need each in every case. Hope it clarifies.
Try these changes:
<!DOCTYPE html>
<html>
<head> <meta charset="UTF-8">
<title>Handlebars Demo</title>
<!-- dependant files -->
<script src="handlebars.js"></script>
</head>
<!-- template -->
<script id="template2" type="text/x-handlebars-template">
<div>Chapter stuff:</div>
<ul>{{#Chapters}}
<ol>{{@index}} {{ChapterName}}
{{#movies}}
<li>Movie ID:{{movieIDnum}}</li>
{{/movies}}
</ol>
{{/Chapters}}
</ul>
</script>
<body><div id="main"></div></body>
<script>
var source = document.getElementById('template2').innerHTML;
var template = Handlebars.compile(source);
var data = [
{
"ChapterName" : "Introduction",
"chapterNum" : "1",
"movies" : [
{
"movieIDnum" : "16244028",
"movieName" : "Update Test Movie 0",
"movieFileName" : "Test0.mov",
"moviePositionInChapter" : "1"
}
]
},
{
"ChapterName" : "Welcome",
"chapterNum" : "2",
"movies" : [
{
"movieIDnum" : " 17322365",
"movieName" : "Update Test movie 1",
"movieFileName" : "Test1.mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 17326267",
"movieName" : "Update Test movie 3",
"movieFileName" : "Test3.mov",
"moviePositionInChapter" : "2"
}
]
},
{
"ChapterName" : "The new Interface",
"chapterNum" : "2",
"movies" : [
{
"movieIDnum" : " 1732123476",
"movieName" : "Update Test movie 12",
"movieFileName" : "Test12.mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 173262373",
"movieName" : "Update Test movie 9",
"movieFileName" : "Test9.mov",
"moviePositionInChapter" : "2"
},
{
"movieIDnum" : " 173273474",
"movieName" : "Update Test movie 10",
"movieFileName" : "Test10.mov",
"moviePositionInChapter" : "3"
}
]
},
{
"ChapterName" : "What is an Update?",
"chapterNum" : "4",
"movies" : [
{
"movieIDnum" : " 177342131",
"chapterNum" : "4",
"chapterName" : "What is an Update?",
"movieName" : "Test movie again",
"movieFileName" : "Test13.mov",
"moviePositionInChapter" : "1"
}
]
},
{
"ChapterName" : "Editing",
"chapterNum" : "5",
"movies" : [
{
"movieIDnum" : " 173290878",
"movieName" : "Update Test movie 14",
"movieFileName" : "Test14mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 177344914",
"movieName" : " Movie 15 Test",
"movieFileName" : "Test233.mov",
"moviePositionInChapter" : "2"
}
]
}
];
var result = template({Chapters: data});
document.write(result);
</script>
</html>
pdjota is right on. This answer is just to show how to use the each block helper if you wanted.
Like pdjota wisely pointed out, you are overwriting the elements of your object because they all have the same key i.e., "Chapter". So turn data
into an array of objects instead of an object of objects that have the same key.
If you do that, you can still pass data
into template()
. What you were missing was how to reference properties of objects used in the each block. That is done with this
. For example, if you are in the movies iterator, properties of the movies object are referenced like this: this.movieIDnum
, this.movieName
, etc.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Handlebars Demo</title>
<!-- dependant files -->
<script src="Handlebars.js"></script>
</head>
<!-- template -->
<script id="template2" type="text/x-handlebars-template">
<div>Chapter stuff:</div>
<ul>
{{#each this}}
<ol>Chapter{{this.chapterNum}}: {{this.ChapterName}}
{{#each movies}}
<li>Movie{{this.moviePositionInChapter}}: {{this.movieName}}</li>
{{/each}}
</ol>
{{/each}}
</ul>
</script>
<body><div id="main"></div></body>
<script>
var source = document.getElementById('template2').innerHTML;
var template = Handlebars.compile(source);
var data = [
{
"ChapterName" : "Introduction",
"chapterNum" : "1",
"movies" : [
{
"movieIDnum" : "16244028",
"movieName" : "Update Test Movie 0",
"movieFileName" : "Test0.mov",
"moviePositionInChapter" : "1"
}
]
},
{
"ChapterName" : "Welcome",
"chapterNum" : "2",
"movies" : [
{
"movieIDnum" : " 17322365",
"movieName" : "Update Test movie 1",
"movieFileName" : "Test1.mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 17326267",
"movieName" : "Update Test movie 3",
"movieFileName" : "Test3.mov",
"moviePositionInChapter" : "2"
}
]
},
{
"ChapterName" : "The new Interface",
"chapterNum" : "2",
"movies" : [
{
"movieIDnum" : " 1732123476",
"movieName" : "Update Test movie 12",
"movieFileName" : "Test12.mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 173262373",
"movieName" : "Update Test movie 9",
"movieFileName" : "Test9.mov",
"moviePositionInChapter" : "2"
},
{
"movieIDnum" : " 173273474",
"movieName" : "Update Test movie 10",
"movieFileName" : "Test10.mov",
"moviePositionInChapter" : "3"
}
]
},
{
"ChapterName" : "What is an Update?",
"chapterNum" : "4",
"movies" : [
{
"movieIDnum" : " 177342131",
"chapterNum" : "4",
"chapterName" : "What is an Update?",
"movieName" : "Test movie again",
"movieFileName" : "Test13.mov",
"moviePositionInChapter" : "1"
}
]
},
{
"ChapterName" : "Editing",
"chapterNum" : "5",
"movies" : [
{
"movieIDnum" : " 173290878",
"movieName" : "Update Test movie 14",
"movieFileName" : "Test14mov",
"moviePositionInChapter" : "1"
},
{
"movieIDnum" : " 177344914",
"movieName" : " Movie 15 Test",
"movieFileName" : "Test233.mov",
"moviePositionInChapter" : "2"
}
]
}
];
var result = template(data);
document.write(result);
</script>
</html>