What I want is to get the current array listing from an "#each" command, so for the first one it returns 0, the following 1, and so on.
I can get the current values within it such as {{this.valueName}}, but how do I get the numerical place in the array?
Edit - Code for context:
{{#each entry}}
{{> childtemplate}}
{{/each}}
<template name="childtemplate">
<p class="list-group-item-heading">
{{#index}}<br>
Name: {{this.name}}
</p>
</template>
Using #index gives me this:
Error: Unsupported directive: #index meteor
Just use {{#index}}. You also don't need this, {{valueName}} is sufficient.
Related
I am using meteor 1.4 for building a real time task assignment app.
I am stuck at a point when i want to include a template passing in an argument the template helper of that template to run.
Now when i pass the argument, it is passed as a string and i want to call that template helper. But i cannot find any way in spacebars to call a template helper when i have the helper name available as a context variable of string type.
Please tell whether it is possible and if yes, then how ??
Thanks in advance
Edit 1 - For ex.
<template name="parent">
{{> children helperParameter="someHelper"}}
</template>
<template name="child">
{{> child2 value=helperParameter }}
</template>
<template name="innerchild">
{{value}}
</template>
So basically, I want to pass the value returned by someHelper to the template innerchild and i want to decide which helper (in this case someHelper) to run in child by passing the name of that helper to child template from parent template.
Now, i can not run that helper in child template where i have its name in parameter helperParameter as a string.
Try Template.dynamic.
<template name="layout">
{{> Template.dynamic template=template}}
<!-- This is equivalent to
{{> nameOfNeededTemplate}}
-->
</template>
Template.layout.helpers({
template: function() {
return 'nameOfNeededTemplate';
}
});
I have the following json object -
{
"type": "typeOne",
"Children": [
{
"ChildType": "ChildTypeOne",
"Settings": {
"IsChildTypeOne": true
}
},
{
"ChildType": "ChildTypeTwo",
"Settings": {
"IsChildTypeTwo": true
}
}
]
}
My handlebars template contains the following snippet -
{{#each Children}}
{{#if Settings.IsChildTypeOne}}
ChildTypeOne!!
{{else}}
ChildTypeTwo!!
{{/if}}
{{/each}}
If I run this data through the template, the only thing that ever renders is ChildTypeTwo!!. So it seems that the if statement isn't properly evaluating IsChildTypeOne. The strange part is that if I put a statement in to display the value of IsChildTypeOne in the else clause, the value is displayed as true for the first ChildType.
Does anyone have any thoughts as to why this is not working as expected?
NOTE - the json posted above is a trimmed down version of my actual object. The real object has nested Children arrays that reuse the same object structure. So for instance, in my example, ChildTypeOne can also have a Childrens array with other objects within it.
EDIT****
So in stepping through the code, I found that if I had my type defined as follows -
...
"Settings" : {
"IsChildTypeOne": 'true'
}
...
it appears to work. Removing the single quoted causes the value to be read as undefined when stepping through.
Given charrs answer didn't seem to help, and the fact that your JSON is more complex than what you've posted, maybe your actual template isn't referencing a parent context correctly? For instance, if you wanted to access the type field in #each children block, it would look like this:
{{#each Children}}
{{#if Settings.IsChildTypeOne}}
{{../type}}
{{/if}}
{{/each}}
This ended up being related to the process being used to serialize the json string into an object. Please see the issue here for an explanation.
Can you try changing the handlebar template code as below:
{{#Children}}
{{#if Settings.IsChildTypeOne}}
ChildTypeOne!!!
{{else}}
ChildTypeTwo!!!
{{/if}}
{{/Children}}
This would iterate your array of Children and would give you result as
ChildTypeOne!!!
ChildTypeTwo!!!
Since your json has two elements one which has ChildTypeOne true and other not.
Sample handelbar:
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{body}}
{{#Children}}
{{#if Settings.IsChildTypeOne}}
ChildTypeOne!!!
{{else}}
ChildTypeTwo!!!
{{/if}}
{{/Children}}
</div>
</div>
The html Output for above template :
<div class="entry">
<h1>My New Post</h1>
<div class="body">
This is my first post!
ChildTypeOne!!!
ChildTypeTwo!!!
</div>
</div>
You can see ChildTypeOne!!! for first element is coming.
Following an example from a book, I have in my .js file
lists = new Mongo.Collection("Lists");
if (Meteor.isClient) {
Template.categories.helpers ({
'Category': function(){
return lists.find({}, {sort: {Category: 1}});
}})
and in my html file:
<body>
<div id="categories-container">
{{> categories}}
</div>
</body>
<template name="categories">
<div class="title">my stuff</div>
{{#each lists}}
<div>
{{Category}}
</div>
{{/each}}
</template>
I have input data this data into lists which uses Category for a field using the console:
> lists.insert({Category:"DVDs", items: {Name:"Mission Impossible"
,Owner:"me",LentTo:"Alice"}});
> lists.insert({Category:"Tools", items: {Name:"Linear Compression
Wrench",Owner:"me",LentTo: "STEVE"}});
but it doesn't output the data.
I think the issue lies in the context of your {{#each}}, you seem to be attempting to access the mongo collection itself rather specific fields through a helper function.
Check out this tutorial on spacebars, it’s a pretty good read http://meteorcapture.com/spacebars/ and also the Meteor Docs section http://docs.meteor.com/#/full/livehtmltemplates. I'm fairly new to Meteor myself but hope that helps.
In your example, you use name Category for 2 different things.
It is the name of template helper function that return an array of list items.
and it is the name of a field item inside your list.
Do the {{#each Category}} to run on the array returned by the helper
Inside the each, you should access the {{Category}} or {{item}} list items
You just need to call your helper lists instead of Category and your code will work:
Template.categories.helpers({
lists: function () {
return lists.find({}, {sort: {Category: 1}});
}
});
{{#each lists}} means: Iterate over a collection cursor (the result of a find) or an array which we get by calling the helper lists. The naming here is somewhat confusing because lists also happens to be the name of the collection your are iterating over.
Inside of the each, the context is a lists document. Each document contains a Category field, which you are outputting inside of a div.
Recommended reading:
A Guide to Meteor Templates & Data Contexts
check to run command : meteor list
it is given to you list of packages which is you used
if autopublish package not in the list you want to publish and subscribe your data here's simple example:
//in server
Meteor.publish('lists',function(){
return lists.find({}, {sort: {Category: 1}});
})
//in client
Meteor.subscribe('lists');
For More Deatails : publish subscription
First: The function in your 'categories' helper shouldn't be between quotes (not sure if that may couse problems).
Second: You are using the {{#each}} loop wrong.
You are calling the 'Lists' collection, but you should call the 'Categories' helper.
<template name="categories">
<div class="title">my stuff</div>
{{#each Category}}
<div>
{{Category}}
</div>
{{/each}}
</template>
Its very confusing your helper has the same name as the field you are calling in the #each loop.
This question already has answers here:
How can I get the index of an array in a Meteor template each loop?
(6 answers)
Closed 7 years ago.
I am using meteor Shark branch.
Is there a way to access array index inside each block helper in spacebars?
I am looking for something like this.
{{#each humans}}
{{this.arrayIndex}}
{{/each}}
meteor >= 1.2
Spacebars gained a lot of functionality in 1.2, including a native #index. Helpers are no longer needed to solve this problem - you can simply do this:
<template name="showHumans">
<ul>
{{#each humans}}
<li>{{#index}}: {{name}}</li>
{{/each}}
</ul>
</template>
meteor < 1.2
I saw a similar example using template helpers in the meteor book in the "animations" chapter. You can apply a map to the humans cursor in order to add an index like so:
Template.showHumans.helpers({
humans: function() {
return Humans.find({}, {sort: {hotness: -1}}).map(function(human, index) {
human.rank = index;
return human;
});
}
});
<template name="showHumans">
<ul>
{{#each humans}}
<li>{{rank}}: {{name}}</li>
{{/each}}
</ul>
</template>
As taken from the spacebars documentation:
You can use a special variable #index in the body of #each to get the
0-based index of the currently rendered value in the sequence.
In Meteor 1.0.2.1, you can do the following:
{{#each humans}}
{{this}}
{{/each}}
This is because #each iterates through the array, making the this in each loop simply equal to the current value.
What is the standard way to access outer #each collection values in the loop?
for example:
<template name="example">
{{#each outerCollection}}
<tr>
{{#each innerCollection}}
<td>{{aaa}}</td>
{{/each}}
</tr>
{{/each}}
</template>
Template.example.aaa = function(){
// cannot access outerCollection values
}
in above Template.example.aaa, this points to the inner collection.
I cannot find way to access outerCollection items.
My solution is like below, I am defining my own helper function.
Is it a standard Meteor way to achieve this purpose?
<template name="example">
{{#each outerCollection}}
<tr>
{{#each innerCollection}}
<td>{{myHelper ../outerItem innerItem}}</td>
{{/each}}
</tr>
{{/each}}
</template>
Handlebars.registerHelper('myHelper', function (outItem, inItem) {
// can access outerCollection via outerItem
});
I found a similar question for the case of inner event handler access.
I think you've answered this yourself! Using ../ is documented in https://github.com/meteor/meteor/wiki/Handlebars.
You can use below code to fetch outer collections.
suppose you have collection called as Collection.Customer and Collection.RechargePlan and you are using both in a template for updating Customer.
Customer = {"name":"James", "rechargeplan":"monthly"};
RechargePlan = [{"rechargeplan": "monthly"},{"rechargeplan": "yearly"}];
//Inside template, Bydefault Customer is available.
{{#each RechargePlan}}
{{#if equals ../rechargeplan rechargeplan}}
//Hurray Plan matches
{{/if}}
{{/each}}
In above code, ../rechargeplan is actually Customer.rechargeplan, ../ actually went one step above heirarchy and then accessed the field if available, since Customer is already available to template, it's field is picked up.