This may be a duplicate question but I've yet to find a solution to my specific problem. I have a db set up like this:
{ "_id" : ObjectId("5c43b0e463ad7e8adfa4f07a"), "name" : "The Box", "price" : "80", "parts" : [ { "pname" : "piccolo", "pprice" : "3" }, { "pname" : "Flute 1", "pprice" : "3" } ] }
Is there a way to iterate through the parts array and do a nested {{#each}} loop so that I can display the name of each document and each part within the name? my code so far:
<tbody>
{{#each pieces}}
<tr class="itemList">
<td class="name">{{name}}</td>
<td class="pdf">PDF</td>
<td class="audio">AUDIO</td>
<td class="format">FORMAT</td>
<td class="price" >${{price}}</td>
<td><input class ="qty" type ="number" name ="quantity" value="0"></td>
</tr>
{{#each parts}}
<tr>
<td colspan="3"></td>
<td class="partName">{{pname}}</td>
<td class="partPrice">{{pprice}}</td>
<td><input class="partQty" type="number" name="quantity" value="0"></td>
</tr>
{{/each}}
{{/each}}
</tbody>
and my helpers:
Template.band.helpers({
pieces: function(){
return bandmusic.find({})
},
parts: function(){
return bandmusic.find({parts})
} })
The first thing to realise is that your
partshelper a) doesn't work and b) isn't what you need anyway.bandmusic.find({parts})doesn't mean "return the parts array from documents in the bandmusic collection", which is what you seem to be wanting it to do.{parts}is ES6 shorthand for{parts: parts}(see this answer). But your function has no variableparts- so in yourfind, what you're really saying is "find documents which match the condition{parts: undefined}What you're trying to do with your nested
#eachis loop through each document in the database, and then within each document, loop through thepartsarray.Well, you get the documents from your
pieceshelper, and each document contains apartsarray, which you can just loop through without needing a helper.Your code should work if you just delete the
partshelper. Blaze has a lookup order which you can read about here. What this means is that when Blaze seesparts, it first thinks "is there a helper calledparts?" - which there is, and it's not working, so nothing happens.But what you want it to think is "Is there a field in the current data context called
parts" - which there is, buthelperscome higher in the lookup order so it never gets there.So the simplest solution in theory is to remove the helper.
As you can see from the
lookup orderlink, it's often unclear what refers to what in Spacebars/Blaze. You can make things much clearer by using the syntax described in the Blaze docs foreachInstead of
#each arrayyou should introduce a new variable to refer to the current item in the array -#each item in array. And then access the item's properties as usual -item.prop1 - item.prop2So your new code becomes: