Access parent template data with Flow Router - meteor

I switched to Flow Router and I have a problem. how can I access the parent template data? with Iron Router the data was coming from router and was available inside the template, so if I wanted to access a parent data Template.parentData() was working.
But in Flow Router the data is not coming from router, it comes from helpers and Template.parentData() doesn't have the data in it anymore!
<template name="myTemplate">
{{#if Template.subscriptionsReady}}
{{> showPost parentPost }}
{{> newPost }}
{{/if}}
</template>
Template.myTemplate.helpers({
parentPost: function(){ return Posts.findOne({...})}
});
Template.newPost.events({
'submit .js-new-post':function(event,template){
console.log(Template.parentData(1).parentPost);
}});

You need to pass that data through to the Template.
E.g. {{> newPost parentPost=mydatahere}}
See more here: http://guide.meteor.com/blaze.html#name-data-contexts

Related

Pulling data from collection using Iron router

I have a small issue. The below code snippet works well if i directly dump it in the body tag
{{#each tasks}}
<ol> <li>Router Name: {{ routerName }}</li>
<li>Router Enable: {{Enable}}</li></ol>
{{/each}}
However, when I wrap it within a template and try call it via a route (iron router), it fails to show the query result.
<template name ='ManagementConfig'
{{#each tasks}}
<ol> <li>Router Name: {{ routerName }}</li>
<li>Router Enable: {{Enable}}</li></ol>
{{/each}}
</template>
Route.js:
Router.route('/ManagementConfig',{ name:'ManagementConfig' });
Everything apart from the above works well within the template and the route. Where am I going wrong?
Your ManagementConfig template don't have access to tasks object. You can fix this by creating a helper method and passing the data.
Template. ManagementConfig.helpers({
'tasks': function(){
//Change this to your task data
return Lists.find({}, {sort: {name: 1}});
}
});

Meteor.js Iron Routing :_id dynamic route confusion

I'm currently working my way though "Your Second Meteor Application" and have been enjoying it so far. Everything I have created works but I do not understand why the following works but the code at the end does not.
Template
<template name="list">
<ul>
{{#each list}}
<li>{{name}}</li>
{{/each}}
</ul>
</template>
<template name="listPage">
<h2>Tasks: {{name}}</h2>
</template>
Route
Router.route('/list/:_id', {
template: 'listPage',
data: function(){
var currentList = this.params._id;
return Lists.findOne({_id: currentList});
}
});
This is giving the expected results. However, I was curious why the following will not work as it seems to be passing the exact same thing. The only differences with the following are:
changing the Router.route('lists/:_id') to Router.route('lists/randomParm')
this.params._id to this.params.randomParm
Template
<template name="list">
<ul>
{{#each list}}
<li>{{name}}</li>
{{/each}}
</ul>
</template>
<template name="listPage">
<h2>Tasks: {{name}}</h2>
</template>
Route
Router.route('/list/randomParm', {
template: 'listPage',
data: function(){
var currentList = this.params.randomParm;
return Lists.findOne({_id: currentList});
}
});
The message I am getting is:
Oops, looks like there's no route on the client or the server for url: "http://localhost:3000/list/TGM9dbRRtspyJy7AR."
Isn't :_id and randomParm holding the same values? An id of list items from the HTML links that are being passed to the routing url and being used to make a mongo call? I don't quite understand how :_id and randomParm are different when I am hitting the same routing URL.
Param shold be with :
So your route will be
Router.route('/list/:randomParm', {
If this param is optional then leave ? after
Router.route('/list/:randomParm?', {

Meteor: Send data to layout template

Say I have the following html.
<template name="Layout">
<div>{{name}}</div>
{{> yield}}
</template>
<template name="Home">
<div>Home Page</div>
</template>
However, data is now passed to Layout. How do I pass data in my home.js file to Layout? (In this case, I want to pass a name to {{name}})
you can use paths in data to refer to called data as in {{../name }}
also Template.parentData([numLevels])
http://docs.meteor.com/#/full/template_parentdata
The most typical way you share data between your .js files and your templates is via 'helpers'. You can create a simple helper to return the data to your Layout template.
In your JS file, put this anywhere:
Template.Layout.helpers({
name: function() {
return myVar;
}
})
If you use something like Iron Router, you can have a more 'global' data context for the route (page) you are on. When you are on a 'route' you can simply do this.myVar if its in the route data context.
Hope this helps.

Meteor: make layout.html WaitOn a subscription?

I'm trying to make a chat (Template.chatlist) feature that sticks to the bottom of the page (similar to the chat function on Facebook, where the chat box is persistent while the page in the background changes as the user browses to other parts of the site). So I put the chat box in a handlebars template on the layout page (so it's not rendering from the {{>yield}} template). The problem is, it's not waiting on the subscriptions before it loads (there is no route to the layout.html, so I couldn't set a waitOn on it in the router), so it's not able to pull information from my users collection.
I need to know, how can I make the layout.html page wait to load after the subscriptions are properly finished? Of course, I can put the chat template inside every page's yield template to have it wait properly, but is there a way where I don't have to do it this way?
<main class="main container" id="central">
{{> yield}}
{{> chatlist}}
</main>
This is sort of what the layout.html looks like right now. The chatlist template is not waiting on any data subscriptions because it's not in the yield section (and thus not controlled by the router)
I also did Template.chatlist.helpers and registered the user data into a helper, but for some reason when I tested it by console logging Users.count the console returns with zero.
Use a region:
<template name="layout">
<aside>
{{> yield region='aside'}}
</aside>
<div>
{{> yield}}
</div>
<footer>
{{> yield region='footer'}}
</footer>
</template>
Router.map(function () {
this.route('home', {
path: '/',
template: 'myHomeTemplate',
layoutTemplate: 'layout',
yieldTemplates: {
'myAsideTemplate': {to: 'aside'},
'myFooter': {to: 'footer'}
},
waitOn: function() {
// ...
}
});
});
See the Iron Router docs.

Can Meteor child templates access parent template helpers?

Say we have a parent template and a child template:
<template name="parent">
{{> child }}
</template>
<template name="child">
{{#if show}}
//Do something
{{/if}}
</template>
If we assign 'show' to the parent template:
if (Meteor.isClient){
Template.parent.show = function(){
return Session.get('isShowing');
}
}
Is there any way for the child template to have access to it?
Edit
You could make a universal handlebars helper so you could use Sessions values anywhere in your html:
Client js
Handlebars.registerHelper('session', function(key) {
return Session.get(key);
});
Client HTML
<template name="child">
{{#if session "show"}}
//Do something
{{/if}}
</template>
Similarly, you could also use {{session "show"}} / {{#if session "show"}} in your parent template and not have to use the Template.parent.show helper anymore.
Regarding the use of ../ notation. There are certain scenarios it may not work: https://github.com/meteor/meteor/issues/563. Basically it works within {{#block helpers}} but not with templates, but it would work in a block helper if it contains a subtemplate.
<template name="child">
{{#if ../show}}
Do something
{{/if}}
</template>
You can also register a common helper :
Template.registerHelper('isTrue', function(boolean) {
return boolean == "true";
});
And call it just like that in your html:
<input type="checkbox" checked="{{isTrue attr}}"/>

Resources