handlebars.js “each” loop inside another “each” loop 3 - meteor

Suppose I want to build a dynamic table. How do I run each inside each. If the only varible that represents current item is this.
{{#each by_width}}
{{#each by_height}}
{{this}} // how do refer to this from the outer loop?
{{/each}}
{{/each}}

You can use ../ to access the parent in a Handlebars template:
{{#each by_width}}
{{#each by_height}}
w: {{../this}}
h: {{this}}
{{/each}}
{{/each}}
That of course assumes that by_height is inside each element of by_width, if they're both at the top level then you'd need another ../:
{{#each by_width}}
{{#each ../by_height}}
w: {{../this}}
h: {{this}}
{{/each}}
{{/each}}
Demo: http://jsfiddle.net/ambiguous/PNTXw/

Don't write {{../this}} but {{..this}}.

Related

Meteor Blaze display array

I have collections like this:
I want to iterate over object.questions.teema for example.
I have helper:
Template.game.helpers({
theGame: function() {
var theGame = Game.findOne({_id:"LhQmaZKW8eJNenyX9"})
console.log(theGame)
return theGame
}
});
and template:
<template name="game">
{{#with theGame}}
{{#each theGame.questions}}
{{teema}}
{{/each}}
{{/with}}
</template>
But it doesnt work, what is wrong with the template?
'#each theGame.questions' Will not work inside the #with, because you can access the 'theGame' object directly.
The point is when you try to get theGame object inside the #with it will return you undefined, because 'theGame' object does not have theGame property, Which you want to access inside #with block.
<template name="game">
{{#with theGame}}
{{#each questions}}
//Thie #each because you have nested array. As I can see in your console log.
{{#each this}}
{{teema}}
{{/each}}
{{/each}}
{{/with}}
</template>
What is {{teema}} supposed to be?
Regardless, as you can see from your console.log statement, {{theGame.questions}} returns another array. But that array returns objects. This is really hard to query for with Blaze.
The better solution would be to flatten it out so that your data is shaped like this:
questions: [
{
a: 'asdfkjah',
level: 'askdjfhal',
q: 'asdkfh',
teema: 'asdkfjh'
vaartus: 100
},
{
...
}
]
This way you don't have an array nested in an array. That will allow you to:
{{#with theGame}}
{{#each theGame.questions}}
{{this.teema}}
{{/each}}
{{/with}}
theGame.questions is an array (that you iterate over) of array of objects which have the teema key. So you still need to iterate over the 2nd level array, or define a specific item in that array before you can eventually reach the object with teema property.
Maybe something like:
{{#with theGame}}
{{#each questions}}
{{#each this}}
{{this.teema}}
{{/each}}
{{/each}}
{{/with}}
But it depends on why you have these 2-level arrays in the first place.

Meteor access parent each value

I have nested each and want to use parent this value.
{{#each county}}
Country name : {{this}}
{{#each state}}
{{this}} is one of the state of {{country}} //here how to use country
{{/each}}
{{/each}}
I have tried {{../this}} but it shows
Can only use `this` at the beginning of a path.
Instead of `foo.this` or `../this`, just write `foo` or `..`.
simply you can do
{{#each county}}
Country name : {{this}}
{{#each state}}
{{this}} is one of the state of {{..}} //here how to use country
{{/each}}
{{/each}}
see {{..}}
EDIT: edited answer

Fastest way to check whether the cursor returned by a template helper is empty?

I often do something like this, using the items helper twice:
{{#if items}}
<h1>Items</h1>
{{#each items}}
{{> item}}
{{/each}}
{{/if}}
Template.foo.helpers
items: ->
Items.find
bar: true
,
sort: created: -1
transform: (item) ->
i.good = true
i
Is Meteor doing extra work in this scenario? Would it be more efficient to switch the if to use something like areItems?
areItems: ->
Items.find
bar: true
.count() > 0
You can use {{else}}
{{#each this}}
{{> item}}
{{else}}
<h1>No Items</h1>
{{/each}}
In the template, you can use {{#with items}} and then either 'this.count' or 'this.length' to check whether your helper returned any items.
Use this.count if 'items' is a cursor, e.g. the result of a find() operation:
{{#with items}}
{{#if this.count}}
<h1>Items</h1>
{{#each this}}
{{> item}}
{{/each}}
{{/if}}
{{/with}}
Use this.length if 'items' is an array:
{{#with items}}
{{#if this.length}}
<h1>Items</h1>
{{#each this}}
{{> item}}
{{/each}}
{{/if}}
{{/with}}
Use #with, #if this.length, and .fetch:
{{#with items}}
{{#if this.length}}
<h1>Items</h1>
{{#each this}}
{{> item}}
{{/each}}
{{/if}}
{{/with}}
Template.foo.helpers
items: ->
Items.find
bar: true
,
sort: created: -1
transform: (item) ->
i.good = true
i
.fetch()
You can do what you want using spacebars' #with block tag.
Like this:
{{#with items}}
{{#if this.count}}<h1>Items</h1>{{/if}}
{{#each this}}
{{> item}}
{{/each}}
{{/with}}
The block tag is documented here. The relevant quote is:
If the argument to #with is falsy (by the same rules as for #if), the content is not rendered.
update: fixed code for desired behaviour. Also while my example demonstrates making one helper call it is better practice to make an 'itemList' template and include it by using {{> itemList items}}.
I found that simply {{#if items.count}} was sufficient.
{{#if items.count}}
<h2>Below there are items</h2>
{{/if}}
{{#each items}}
<div class="item-name">{{this.name}}</div>
{{else}}
<h2>There are no items</h2>
{{else}}

Any way to pass an element from one context to another?

I have a meteor template that looks something like the following. Essentially I would like to pass something from my parent template to my child. Is there a way to do this?
<template name="parent">
Hello my name is {{name}}
{{#each children}}
{{> child}}
{{/each}}
</template>
<template name="child">
Hello my name is {{child_name}} and my parent's name is [not sure what to do]
</template>
Any help would be greatly appreciated!
Use the dotdot operator to traverse to parent views.
<template name="parent">
Hello my name is {{name}}
{{#each children}}
{{> child}}
{{/each}}
</template>
<template name="child">
Hello my name is {{child_name}} and my parent's name is {{../name}}
</template>
See demo here and documentation here

handlebars: how to access an array?

I have the following simplified document:
{
channel:'Channelname',
users: [
{userId:1},
{userId:2},
{userId:3}
]
}
How can i access the userId's in a {{#each}} loop like so:
{{#each channels}}
{{channel}}
{{#each channels.users}}
{{userId}} //or {{channels.users.userId}} ?
{{/each}}
{{/each}}
The first {{#each}} loop prints my channelname as expected, but the second {{#each}} loop doesn't print anything.
Regards, Cid
Use
{{#each channels}}
{{channel}}
{{#each users}}
{{userId}}
{{/each}}
{{/each}}
When going into an each loop, handlebars will use the key names in the array directly.

Resources