Handlebars #each syntax is giving me problems

Viewed 31

The code inside {{#foods}} doesn't work and I don't know what to do.

<div class="container">
    <div class="options">
        {{#meal}}
            <h3>Select the food you want to add to {{name}}</h3>
            <div class="options-items">
                {{#foods}}
                    <a class="test" href="http://localhost:8000/dashboard/add/{{meal.id}}">
                        {{foods.name}}
                    </a>
                {{/foods}}
            </div>
        {{/meal}}
    </div>
</div>

This is my context data:

{
"meal":
    [{
        "id":2,
        "name":"Lunch"
    }],
"foods":
    [{
        "id":1,
        "name":"Banana",
        "kcal":89,
        "carb":22.84,
        "prot":1.09,
        "fats":0.33
    },
    {
        "id":2,
        "name":"Chicken",
        "kcal":144,
        "carb":0,
        "prot":21,
        "fats":2.6
    },
    {
        "id":3,
        "name":"Milk",
        "kcal":47,
        "carb":4.9,
        "prot":3.3,
        "fats":1.6
    }]
}
1 Answers

Three things:

First, foods is a sibling of meal in your data. Handlebars is context-aware. The way you have {{#foods}} nested under {{#meal}} tells Handlebars to look for foods as a property of each meal. This is incorrect. We need to use a "path" to tell Handlebars to step-up a level. The path won't play nicely with your {{#foods}} syntax, so I am going to use the more conventional {{#each}}. The template becomes:

{{#each ../foods}}
  <a class="test" href="http://localhost:8000/dashboard/add/{{meal.id}}">{{foods.name}}</a>
{{/each}}

Second, as I mentioned in the comment, name is not a property of the foods array. Instead, you should just use {{name}} to reference the name of the currently iterated item from the foods array. Now our template becomes:

{{#each ../foods}}
  <a class="test" href="http://localhost:8000/dashboard/add/{{meal.id}}">{{name}}</a>
{{/each}}

Third, {{meal.id}} will not work. As I mentioned above, Handlebars is context-aware. This means that when it is within the {{#each foods}} loop, the {{meal.id}} is telling Handlebars to find the id of a meal object belonging to the currently iterated item in foods. Instead, we will need to use a path again to get back to the "meal-level" of our template execution:

{{#each ../foods}}
  <a class="test" href="http://localhost:8000/dashboard/add/{{../id}}">{{name}}</a>
{{/each}}

Here is a fiddle for reference.

Related