I am having problems understanding how to loop through an object in Handlebars and possibly passing information from one place to another.
Below is a sample json file which I need to read from. In this example, it’s just a bunch of image file names that I want to pull in.
This json file is called “testdata.json” and it has:
{ "artists": [ { "name": "person 1", "artwork": ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"] }, { "name": "person 2", "artwork": ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"] }, { "name": "person 3", "artwork": ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"] }, { "name": "person 4", "artwork": ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"] } ] }
And in app.js, I require it to a variable by the same name testdata
.
const testdata = require('./data/testdata.json');
Then I pass it in alongside “app” to my homepage route file via
homepageRoute(app, testdata);
I want to get the array with image filenames from testdata, pass it in to the homepage (index.hbs) via a route, and then let handlebars iterate over the array to form a mini image gallery.
Here is what my sample routes file for the homepage looks like:
module.exports = function homepageRoute(app, testdata){ app.get('/', function(request, response){ var TestWholeArray = testdata.artists[0].artwork; response.render('index', { pageTitle : "Home Page", pageId : "home", artistArtwork : TestWholeArray }); }); }
When I do:
Handlebars in index:
{{#each artistArtwork}} <div class="PICSHERE"> <img src="images/artwork/{{artistArtwork}}" alt=""> </div> {{/each}}
The images don’t appear, and when I look at the back end code via the console, I see this come out:
<div class="PICSHERE"><img src="images/artwork/"" alt=""></div> <div class="PICSHERE"><img src="images/artwork/"" alt=""></div> <div class="PICSHERE"><img src="images/artwork/"" alt=""></div> <div class="PICSHERE"><img src="images/artwork/"" alt=""></div>
The filename never comes out. When testing and trying to console.log(TestWholeArray );
in terminal, I do see and get this:
[ 'pic1.jpg', 'pic2.jpg', 'pic3.jpg', 'pic4.jpg' ]
To minimize the test even further, when I take the same test above, but instead of using this:
var TestWholeArray = testdata.artists[0].artwork;
I dig a little deeper into the array to pull in just one image as oppose to all of them via:
var TestWholeArray = testdata.artists[0].artwork[0];
Then it does work and the image does appear. It’s when I try to pass in more than one that it goes bonkers.
What am I doing wrong or what am I missing?
Advertisement
Answer
When looping an array, use {{this}}
to access the current value.
{{#each artistArtwork}} <div class="PICSHERE"> <img src="images/artwork/{{this}}" alt=""> </div> {{/each}}
What you were trying to do, is to access the property artistArtwork
from the array artistArtwork
which of course, doesn’t exist.
Working demo:
let data = { "artists": [ { "name": "person 1", "artwork": ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"] }, { "name": "person 2", "artwork": ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"] }, { "name": "person 3", "artwork": ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"] }, { "name": "person 4", "artwork": ["pic1.jpg", "pic2.jpg", "pic3.jpg", "pic4.jpg"] } ] }; let artistTemplate = `{{#each artistArtwork}} <div class="PICSHERE"> <img src="images/artwork/{{this}}" alt=""> </div> {{/each}}`; let template = Handlebars.compile(artistTemplate); console.log(template({ artistArtwork: data.artists[0].artwork }));
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.8/handlebars.js"></script>