Parameter isn't passed into nested template - meteor

I'm doing category sidebar template for online shop. I will use that in 2 places - on customer, and admin side. Each one will have own service of clicking on category. I want to pass parameter "redirect" which will decide what action will be done, but the problem is, that parameter isn't visible in nested templates - only in 1st level categories.
HTML :
<template name="categoriesSidebar">
<ul>
{{#each mainCategories}}
<li>
{{> categoriesSidebarItem redirect=true data=this }}
</li>
{{/each}}
</ul>
</template>
<template name="categoriesSidebarItem">
<a href="#">
{{data.name}}
</a>
{{#if data.subCategories.length}}
<ul>
{{#each subCats }}
<li>
{{> categoriesSidebarItem redirect=redirect data=this }}
</li>
{{/each}}
</ul>
{{/if}}
</template>
Javascript :
Template.categoriesSidebar.helpers({
mainCategories: function() {
return Categories.find({'categoryLevel' : 1});
}
});
Template.categoriesSidebarItem.helpers({
subCats : function(){
return Categories.find({_id:{$in: this.data.subCategories}});
}
});
Template.categoriesSidebarItem.events({
'click a' : function(event){
if(this.redirect == true){
Router.go('category',{_id : this.data._id});
return false;
}else{
//categoryId is ReactiveVar used in another template
categoryId.set(this.category._id);
}
}
})
Result :
Women
Nike
Men
Nike
Adidas
Women and Men category work well , after clicking on them, "redirect" is seen as true and Router redirects to desired route, but for nested categories, "redirect" parameter is undefined.
How to pass that parameter to nested template ?

Change the code to this:
{{#if data.subCategories.length}}
<ul>
{{#each subCats }}
<li>
{{> categoriesSidebarItem redirect=../redirect data=this }}
</li>
{{/each}}
</ul>
{{/if}}
The each block changes the data context, so you need to retrieve redirect from the parent data context. That's what ../ does.

Related

Meteor with Blaze: My helper is not working with {{ #each }} loop

I am using Blaze with Meteor.
I have announcements_list.html
<template name="AnnouncementsList">
<div class="announcements">
<ul class="collection">
{{ #each announcements }}
{{ >announcementItem }}
{{ /each }}
</ul>
</div>
</template>
And announcements_list.js
Template.AnnouncementsList.helpers({
announcements: function() {
return Announcements.find({}, {sort: {createdAt: -1}});
}
});
If I remove the {{ each }} loop, i can read {{ >announcementItem }}. So I think the problem is the function in the helper. Help me please =.= ...
Is there an announcementItem in your Announcements db or are you trying to access data from a template? If the former, your blaze call should be {{announcementItem}}. In an #each, #unless or #with there is no arrow needed.
You are rendering the same template for every item in announcements. Where this template get data from? I would make something like this:
<template name="AnnouncementsList">
<div class="announcements">
<ul class="collection">
{{#each item in announcements}}
{{> announcementItem item}}
{{/each }}
</ul>
</div>
</template>
Then full item object will be accessible in your announcementItem through
Template.instance().data in helpers and events
this.data in onCreated and onRendered.

Meteor: There is no route for the path error. how to access SINGLE article within a nested object

I have an array of 10 objects 'categories' and each category has sub objects such as posts within that category. This is how it looks.
I access the category list like this.
<template name="CategoriesMain">
{{#each articles}}
<li>
<h2>{{name}}</h2>
</li>
{{/each}}
</ul>
</template>
this link
<h2>{{name}}</h2>
accesses the 'posts' list within the category which looks like this
<template name="CategoriesSingle">
<h1>This is a test</h1>
<ul>
{{#each articles}}
{{#each posts}}
<li>
<h2>{{title}}</h2>
</li>
{{/each}}
{{/each}}
</ul>
</template>
this link is supposed to target the SINGLE POST from the post list within the category
<h2>{{title}}</h2>
PROBLEM:
I get the error: There is no route for the path: /catsingle/ when ever i try to access the SINGLE POST
even though i have it in my routes.js like this
FlowRouter.route('/catsingle/:_id', {
name: 'catsingle',
action() {
BlazeLayout.render("AppLayout", {main: "CategoryArticleSingle"});
}
});
the template helper looks like this
Template.CategoryArticleSingle.helpers({
articles: function () {
var id = FlowRouter.getParam('_id')
return CategoryCollection.findOne({_id: id});
}
});
How can I successfully the single post within a category?
Your posts array doesn't have an _id key, it has an ID key.
Try:
<h2>{{title}}</h2>

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.

Meteor accounts-list

I want to display all registered accounts in my meteor app. I published and subscibed to the Meteor.users collection and build a template to show email-addresses. The problem is I don't understand how I should navigate the data.
<template name="contacts">
<br>
<ul class="list-group">
{{#each users}}
<li class="list-group-item">
<span class="badge">14</span>
{{emails}}
</li>
{{/each}}
</ul>
</template>
{{emails}} is an array with json-objects and I don't know how to handle it to get the "address" field displayed.
This is my JS:
Template.kontakte.users = function (){
return Meteor.users.find();
}
First create a subtemplate, looks better:
<template name="contacts">
<ul class="list-group">
{{#each users}}
{{> user}}
{{/each}}
</ul>
</template>
<template name="user">
<li class="list-group-item">
<span class="badge">14</span>
{{email}}
</li>
</template>
In template user the userObject is available via this pointer. The email can be shown with helper functions.
Template.user.helpers({
email: function() {
return this.emails[0].address;
}
});
Note, this just shows the first email in your array.

Resources