Meteor: make layout.html WaitOn a subscription? - meteor

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.

Related

How to route html pages on clicks in meteor?

I am a newbie in Meteor. I am developing an app having a login page that must redirect to certain pages as per the login id.There are certain click events which opens up html pages.I have the hard code data in the pages to check the flow now.I have the html pages as well designed, but I am not able to link them for click events and login. Please help.
Here is one way to do it:
In your HTML file, something like this:
<head>
<title>Duckbilled Platypus</title>
</head>
<template name='layout'>
{{> banner}}
{{> yield}}
</template>
<template name="banner">
<h1 class="chocolatefont">Platypi of the World Unite! (Duckbilled, that is)</h1>
<hr/>
</template>
<template name="main">
<div id="templateMain" name="templateMain">
<h2>RAVES</h2>
<p>No Raves yet</p>
<h2>RANTS</h2>
<p>No Rants yet</p>
<h2>RANDOM</h2>
The Legend of NFN Oscar
<br/><br/>
NFN Oscar's donut
<br/><br/>
Alliteration Station ("Ben's Bizarre Bazaar")
<br/><br/>
Boomeranging Telescopic and Kaleidoscopic Phrase Mazes
<br/><br/>
Acrostics
<br/><br/>
Homonym Homie
</div>
</template>
...and then add whichever templates you want for the pages you want to route to; in my case, it's one for each "href" referenced in the anchor tags (nfnoscar, nfnoscarsdout. etc.)
The "yield" (which means, "insert here whatever the router says corresponds to the URL") requires Iron:Router, which you say you already have.
In your JS file, something like this:
Router.configure({
layoutTemplate: 'layout'
});
Router.route('/', {
name: 'main',
template: 'main'
});
Router.route('/nfnoscar', {
name: 'nfnoscar',
template: 'nfnoscar'
});
Router.route('/nfnoscarsdonut', {
name: 'nfnoscarsdonut',
template: 'nfnoscarsdonut'
});
Router.route('/alliterationstation', {
name: 'alliterationstation',
template: 'alliterationstation'
});
Router.route('/btakpm', {
name: 'btakpm',
template: 'btakpm'
});
Router.route('/homonyms', {
name: 'homonyms',
template: 'homonyms'
});
Router.route('/acrostics', {
name: 'acrostics',
template: 'acrostics'
});
Now, whichever link is clicked, the corresponding page is loaded by means of the "yield" and the Iron Router routing.
You can see this particular app and how it works when you click the links, etc., at my "sandbox" Meteorsite here.

Router for static site using Meteor

I'm new to Meteor and have limited experience with javascript. I've searched all the stack post and the web for a good tutorial on how to use the Iron Router package to route static pages and just can't seem to figure it this out. I would love to have someone help me understand how to setup a router.js file for Home and About. I've played with my code a lot but this is what I had before posting here. Conseptually I seem to be struggling to grasp how the routing works and all the various features of iron router and then connecting these routes into a nav bar where I can navigate between them. Thank you in advance for any help you can provide.
client/templates/application/layout.html
<template name="layout">
<div class="container">
{{> yield}}
</div>
</template>
lib/router.js
Router.configure({
layoutTemplate: 'layout'
});
Router.route('/', function () {
this.render('home', {
template: 'home'
});
this.render('about', {
template: 'about'
});
});
templates/home.html
<template name="home">
<div class="container">
<h2>Home</h2>
</div>
</template>
The code you have above looks correct.
One quirk is you're rendering two pages for your / route. You should have this:
Router.route('/', function () {
this.render('home', {});
});
Router.route('/about', function() {
this.render('about', {});
});
Remember this.render takes the first param as the template, so there's no need to define it separately anymore.
And a new about.html page:
<template name="home">
<div class="container">
<h2>Home</h2>
</div>
</template>
Now you can use the / and /about pages (at least I hope i've not missed anything)
You can have 3 templates on your folder
Client/Views
with the name of
about.html
main.html
admin.html
layout.html
(for example)
So in the about.html you have this
<template name="about">
<h1> hello from about page
</template>
<template name="main">
<h1> hello from about page
</template>
<template name="admin">
<h1> hello from about page
</template>
the Layout.html file need con taints this yield rendered.
<template name="layout">
{{> yield}}
{{admin}}
{{about}}
{{main}}
</template>
So you can use layout template as a master page and calling that 3 templates separates by a route, how to assign a route and telling meteor to use that layouts, well use this js code
JS
Router.configure({
layoutTemplate: 'layout'
});
Router.map(function(){
this.route('admin', {path: '/admin'});
});
Router.map(function(){
this.route('about', {path: '/about'});
});
Router.map(function(){
this.route('main', {path: '/'});
});
At least this works for me bro, hope this work for you

Why iron-router does not render carousel?

it works perfectly when I make it like this
<body>
{{> carousel}}
</body>
<Template name="carousel">
....here the code of carousel...
</Template>
but when I use iron-router to render the Template; it does not render carousel
<body>
{{rendreRouter}}
</body>
<Template name="carousel">
....here the code of carousel...
</Template>
Router.map(function () {
this.route('carousel',{
path: '/'
});
});
I'm coming to the conclusion that the documentation you're reading is not in sync with the code base. In fact, it looks like the feature is gone.
In my own exploration of the topic, I have an alternate solution at that may work for you at the bottom of this post.
Init your carousel in template.rendered hook, for example my template is named main_slider.
Template.main_slider.rendered = function() {
// init carousel here
};

How can I use two Iron Router controllers in one layout in Meteor 0.8.0?

In my Meteor app, I have two yield blocks: one for my global navbar and the other for my main content:
<template name="layout">
<div>
{{> yield region='navRegion'}}
</div>
<div>
{{> yield}}
</div>
</template>
How can I add an Iron Router Controller into my routes so that I can pass data into my global navbar (since it doesn't have a route)? Is it possible to run the two controllers at the same time? Or do I have to rely on helpers for the global nav?
Let's say the template that you were trying to render in the main {{> yield}} was named home. The following would work.
Router.configure({
layoutTemplate: 'layout'
});
Router.map(function () {
this.route('home', {
path: '/',
template: 'home',
yieldTemplates: {
'navRegion': {
to: 'navRegion'
}
}
});
});
Here's the answer from #cmather, which he answered on my other post:
How do I activate an Iron Router route without changing the path?
There is a one-to-one between a route and a route controller. You'll
only ever have one controller running at a time, based on the route
you're on. If you want to set a global value from a controller, and it
doesn't make sense to do it in the global data context, you can always
set a session value. For example: Session.set('currentId',
this.params._id) - #cmather

Router only render certain templates

I have a layout with 2 containers 1)productView and 2)calendarView. My Router is configured as follows:
this.route('productDetail', {
layout: 'main',
path: '/products/:_id',
waitnOn: function(){...},
data: function(){...},
yieldTemplates: {
'calendarView: { to: calendar }
}
});
I now want to achieve that whenever the route changes (e.g. from 'products/1' to 'products/2') only the productView is re-rendered and that calendarView does nothing. As for now every time the 'productDetail/:id' route is called the 'calendarView' function 'Template.calendarView.rendered' gets called and re-renders the template. My 'main' template looks like this:
<template name="main">
<div>
{{yield}}
</div>
<div>
{{yield 'calendar'}}
</div>
</template>
Is there a way to tell the router to only render certain templates? Or is there a better solution?
Any help is much appreciated.
Is there a reason why you use the router for the calendar view ?
I think one solution may be not to use the router for the calendar view
<template name="main">
<div>
{{yield}}
</div>
<div>
{{>calendar}}
</div>
</template>

Resources