Reputation: 3383
I am using handlebars to iterate over a nested array and display the data using a handlebars template, but I need to access a property that is not part of the array that I am iterating over. When the array is not nested, this works as expected. Here is an example (you can paste these directly into tryhandlebars):
Template:
<div class="entry">
<div class="body">
{{#each items}}
<p>{{name}} - {{quantity}} {{../currency}}</p>
{{/each}}
</div>
</div>
Data:
{
currency: 'GBP',
items: [
{
name: 'apples',
quantity: 5
}, {
name: 'bananas',
quantity: 7
}
]
}
But now I have a requirement to pass a whole new data structure to the template, so I am wrapping the fruit data as a property of another object:
{fruit: {
currency: 'GBP',
items: [
{
name: 'apples',
quantity: 5
}, {
name: 'bananas',
quantity: 7
}
]
}}
I change the #each
to iterate over fruit.items
instead of items
:
{{#each fruit.items}}
<p>{{name}} - {{quantity}} {{../currency}}</p>
{{/each}}
Now, the name and the quantity are outputted correctly as before but the currency is blank. It seems the relative reference using ../currency
no longer works. The only difference is the dot notation in the value passed to the each
. How can I use the relative path in a nested property?
I have tried creating a helper function that takes the relative reference so I can inspect the values and can see the currency reference is undefined.
Upvotes: 1
Views: 1449
Reputation: 8993
There is a little confusion here as to what the parent context is when within the #each
.
As a tip, a good way to discover the parent context is to use Handlebars' built-in log helper.
Within our #each
we can add {{log ..}}
and Handlebars will print to the console the value of our parent.
In this case we get:
{
fruit: {
currency: 'GBP',
items: Array(2) [...]
}
}
This tells us that our parent is the root context and not the fruit
object. This makes sense because we never "step-into" the context of fruit
- for example, by using {{#with fruit}}{{#each items}}
- but instead iterate fruit.items
directly from the root.
This means we need only change our ../currency
to ../fruit.currency
. An alternative would be to use Handlebars' @root data variable to jump to our root context directly: @root/fruit.currency
.
A second alternative is to use the #with
helper as mentioned above. This creates a fruit
context, allowing us to leave the #each
part of the template as you had it in your post:
{{#with fruit}}
{{#each items}}
<p>{{name}} - {{quantity}} {{../currency}}</p>
{{/each}}
{{/with}}
I have created a fiddle for your reference.
Upvotes: 4