Iterating through arrays of objects in meteor templates - meteor

[
{name:"foo",last:"bar",age:100},
{name:"baz",last:"foobar",age:200},
]
Is there a way on how to iterate that to a meteor template using {{#each}} helper like
<template name='boo'>
{{#each objectInArray}}
<span> {{namehere}} </span>
{{/each}}
</template>

You can do it like this:
<template name="boo">
{{#each objectInArray}}
<span> {{foo}} </span>
<span> {{last}} </span>
<span> {{age}} </span>
{{/each}}
</template>
Template.boo.objectInArray = function() {
return [
{name:"foo",last:"bar",age:100},
{name:"baz",last:"foobar",age:200},
]
}

Related

when to reference a property that is not a valid identifier, how can I use segment-literal notation?

In the document handlebars
{{#each articles.[10].[#comments]}}
<h1>{{subject}}</h1>
<div>
{{body}}
</div>
{{/each}}
but I want such use it
{{#each nav-list.value}}
<li class="nav-{{#index}}">
{{{../[content.value].value}}}
</li>
{{/each}}
Obviously, it dons't work! How should I implement this...

I lose data context when i generate template with parameters

when I generate subtemplate in #each helper and i add parameter, then i lose data context, what is normally visible.
I found workaround by passing data fields to template by
{{> productItem parameter="test" name=name details=details}}
, but for more complicated collections that would be very tiresome... isn't there better option to solve that problem ?
<template name="main">
{{#each products}}
{{> productItem parameter="test"}}
{{/each}}
</template>
<template name="productItem">
<div class="product">
<p>{{name}}</p>
<p>{{details}}</p>
<p>{{parameter}}</p>
</div>
</template>
And javascript :
Template.main.helpers({
products: function(){
return Products.find({});
}
});
you are creating a new context ( it doesn't magically merge everything ), but its easy enough to include the original context.
you go :-
{{> productItem product=this parameter="test"}}
then
<template name="productItem">
<div class="product">
<p>{{product.name}}</p>
<p>{{product.details}}</p>
<p>{{parameter}}</p>
</div>
</template>
or
<template name="productItem">
<div class="product">
{{#with product}}
<p>{{name}}</p>
<p>{{details}}</p>
{{/with}}
<p>{{parameter}}</p>
</div>
</template>

How to create a template helper pathFor path

Usually I just do {{pathFor 'dashboard'}}
But what if I get the path 'dashboard' from template helper as {{name}}
I can't do this{{pathFor '{{name}}'}} but I need to!
It's a submenu which looks like:
{{#each connectedChannels}}
{{> submenuChannel}}
{{/each}}
<template name="submenuChannel">
<li>
<span class="sidebar-text">{{name}}</span>
</li>
</template>
It should work if you remove the quotes and braces around name:
<a href="{{pathFor name}}">

How to do recursive templates in Meteor?

rather a theoretical question - how can I render recursive templates in Meteor? For example, displaying a comment on comment with unlimited number of comment sub-levels so that HTML would be diplayed as the following?
<section>
some text
<section>
nested text
<section>
further nested text and sections
.....
</section>
</section>
</section>
In my case I pass to the "tree" template a mongoDB document and this document can have unlimited number of sub-content levels. My example below doesn't work the way I want.
<template name="tree">
<div class="wrapper" style="border:1px solid red">
<ul>
{{#each getStructure}}
<li>
{{#each content}}
<ul>
<li>
<a class="item">{{text}}</a>
<!-- TODO: this stuff needs to be recursive.
{{#if sub_content}}
<ul>
{{#each sub_content}}
<li>
<a class="item">{{text}}</a>
{{#if sub_content}}
....
{{/if}}
</li>
{{/each}}
</ul>
{{/if}}
</li>
</ul>
{{/each}}
</li>
{{/each}}
</ul>
</div>
</template>
A simplified example of recirsuve, say you had a post sample template of:
<template name="post">
{{post_text}}
{{#each comments}}
{{>comment}}
{{/each}}
</template>
and a post helper of:
Template.post.helpers({
comments: function() {
return CommentCollection.find({post_id: this._id, parent_id: {$exists: 0}});
}
});
I would create a template for the comment layout and provide a helper in that for sub-comments, depending on your data structure something like the following:
<template name="comment">
{{comment_text}}
{{#each sub_comment}}
{{> comment}}
{{/each}}
</template>
and then the helper along the lines of:
Template.comment.helpers({
sub_comments: function() {
return CommentCollection.find({parent_id: this._id});
}
});
This would recursively produce the comments template for each sub-comment then roll back up the tree to the next #each and then print that comment and all of its sub-comments etc.

Polymorphism in Meteor Templates

Say I have a Meteor application which displays widgets. A widget can have one of several forms:
<template name="textWidget">
<h1>{{myTitle}}</h1>
<p>{{myTextContent}}</p>
</template>
<template name="imgWidget">
<h1>{{myTitle}}</h1>
<img src="{{myImagePath}}" />
</template>
<template name="listWidget">
<h1>{{myTitle}}</h1>
<ul>
{{#each items}}
{{> listWidgetItem}}
{{/each}}
</ul>
</template>
Is there a good pattern for rendering a specific template given a record type?
Naively, I can do something like:
<template name="masterTemplate">
{{#each widgets}}
{{#if widgetType "text"}}
{{> textWidget}}
{{else}}
{{#if widgetType "img"}}
{{> imgWidget}}
{{else}}
{{if ... }} ... {{/if}}
{{/if}}
{{#/if}}
{{/each}}
</template>
With a helper like:
Template.masterTemplate.widgetType = function(cmp) {
return cmp === this.data.type;
};
This seems like a very clunky and unflexible way to operate though. Am I missing an obvious library or design pattern for this use case?
You can try something like this:
UI.registerHelper('widget', function () {
var templateName = this.data.type + 'Widget';
return Template[templateName].extend({ data: this });
});
and you can use it as follows:
{{> widget context}}
or
{{#with context}}
{{> widget}}
{{/with}}

Resources