Set a reactive layout in Meteor with Iron Router - meteor

Is there a way to set a reactive layout in meteor with iron router?
For example:
Router.configure({
loadingTemplate: 'loading',
layoutTemplate: Session.get('fullscreen') ? 'layoutFull' : 'layout'
});
Then a link in both layouts with:
Toggle Fullscreen
And then in both layouts something like this:
Template.layoutFull.events({
'click [data-action=toggleFullscreen]': function() {
Session.set('fullscreen', !Session.get('fullscreen'));
}
});
Template.layout.events({
'click [data-action=toggleFullscreen]': function() {
Session.set('fullscreen', !Session.get('fullscreen'));
}
});
The issue I'm running into is Router.configure isn't setting layoutTemplate reactively. Is there a way to do this so it affects all routes?

It has to be a function to be reactive:
layoutTemplate: function(){
return Session.get('fullscreen') ? 'layoutFull' : 'layout'
}
Also, why two functions?
You need just one since this is the negation of clicked Session

Related

Using a second master layout

I have one master layout that i have been using for my app.I have a generated my app using iron-cli package and my master layout is called master_layout.html
t i now have a problem. All my app menus are all in he master layout and i need to create a login page that will not require the menus. This can be solved,if i had a second master layout whereby i can strip the menus off my original master layout and use the layout for my login page.
My route looks like this
Router.route('/Limit/ay', {
name: 'ay',
controller: 'LimitController',
action: 'ay',
where: 'client'
});
and my controller code looks like this
ay: function() {
this.render('Ay');
//this.render('Added', {});
}
Is there a way i can register a second master layout and use it for my login page?.
If i register another layout
Router.configure({
layoutTemplate: 'MasterLayout',
loadingTemplate: 'Loading',
notFoundTemplate: 'NotFound'
});
Router.configure({
layoutTemplate: 'GoodLayout'
})
One layout is being used and the other is ignored,so i can only use one main layout at a time.
How can i solve this?.
Just override the layout in your new route:
Router.route('/Limit/ay', {
name: 'ay',
layoutTemplate: 'GoodLayout',
controller: 'LimitController',
action: 'ay',
where: 'client'
});
The route's version will take precedence over the global layout setting.

Meteor's iron:router loadingTemplate not rendered

I have the following code:
Router.configure({
layoutTemplate: 'commonTemplate',
loadingTemplate: 'loadingApp'
});
Router.route('/configuration', {
name:'configuration',
template:'configuration',
onBeforeAction: function(){
this.layout(null);
if (Session.get('appReady')){
this.next();
} else {
console.log("loading app...");
this.render('loadingApp');
}
}
});
"loading app..." is correctly shown on console.
However during that time (waiting for session variable), no loading template (neither from Router.configure; nor from this.render) is displayed.
Also when the session variable is true, the configuration template is rendered correctly.
Is this an iron:router bug or I'm doing something wrong?
Your code is working for me, maybe the problem is that your loading template isn't showing the loading content properly. I tested the code with the loading template from the https://atmospherejs.com/sacha/spin package and worked fine.
You could install from atmospherejs the package sacha:spin and configure Iron Router to use the loading template, this package is easy to use, you have to use the template 'loading' where you want the loading animation.
1) meteor add sacha:spin
2) In your router file :
Router.configure({
loadingTemplate: 'loading'
});
Router.route('/test', {
name: 'test',
template: 'test',
onBeforeAction : function()
{
this.layout(null);
if (Session.get('appReady')){
this.next();
} else {
console.log("loading app...");
this.render('loading');
}
}
}
);

Iron-router set notFoundTemplate when no data found in database

How can I set a layout when my data function returns null.
For example, in the route below, when chefs is null, I would like to render my 'notFound' template.
Router.route('/vendors/chefs/:_url', {
template: 'chefs',
data: function() {
var chefs = Chef_db.findOne({url: this.params._url});
return chefs;
}
});
Take a look at the notFoundTemplate in the documentation: https://github.com/iron-meteor/iron-router/blob/devel/Guide.md
You can apply it globally:
Router.plugin('dataNotFound', {notFoundTemplate: 'notFound'});
Or you can apply it to specific routes using the except/only options:
Router.plugin('dataNotFound', {
notFoundTemplate: 'NotFound',
except: ['server.route']
// or only: ['routeOne', 'routeTwo']
});
There's a built-in plugin for that. It's called dataNotFound. It's mentioned in the iron:router guide.

Is there a way to prevent the loadingTemplate from showing up on "fast" routes?

Most of the time, my search returns so fast that it's not worth flashing the loading template to the user...(in fact, it's distracting, as people are fine with a blank screen if the results are coming a split second later)...Is there any way to prevent the loading template from showing if the waitOn is only waiting for a short amount of time?
Here's my configuration
Router.route('/search', {
waitOn: function () {
return searchSubsManager.subscribe("search", Session.get('searchString'));
},
action: function () {
this.render('searchResults');
}
});
I saw that with this package:
https://github.com/Multiply/iron-router-progress
you can control whether it shows up for fast routes, but I don't need all that functionality, nor do I want the progress bar it provides... I'm just wondering if the basic iron router/ waitOn functionality can provide this ability.
There is not configuration to use on the waitOn function, but Why don't you create another layout template, and use it to show that fast routes?
<template name="noLoading">
{{> yield}}
</template>
Router.map(function () {
this.route('fastRoutes', {
path: '/someRoutes',
template: 'myHomeTemplate',
layoutTemplate: 'noLoading',
});
});
Update
or use the sacha:spin package and change the class name depending on the duration of the query.
if(queryDuration){
Meteor.Spinner.options = {
className: 'none'
}
}else{
Meteor.Spinner.options = {
className: 'spinner'
}
}

Load spinner while loading

I want to load a spinner when my account page is loading, it is taking a bit time to load "myaccount" page so i want to load a spinner using spinner atmosphere package.
Here is my code,where do i need to add {> spinner} to load the spinner
this.route('myaccount', {path:'/myaccount/',
fastRender: true
});
for myaccount,it need to contact 3rd party api to load some data to page.
Suggest me which is the best place to load spinner
If you use NProgress preloader then you can achieve it like that:
this.route('myaccount', {
path:'/myaccount/',
action:function(){
self = this;
self.render('header', {to:'header'});
NProgress.start();
// load external data and onComplete (callback) it renders template and stops preloader
MyAccount.loadData(function(){
self.render(self.template);
NProgress.done();
})
}
});
Update :
Standard solution for using Spinner with Meteor subscription mechanism is using waitOn function:
<template name="loadingTemplate">
{{>spinner}}
</template>
<template name="layout">
<nav>
{{> yield region='header'}}
</nav>
{{> yield}}
<footer>
{{> yield region='footer'}}
</footer>
</template>
Router.configure({
loadingTemplate: 'loadingTemplate',
layoutTemplate: 'layoutTemplate',
yieldTemplates: {
'header': { to: 'header' },
'footer': { to: 'footer' }
}
});
//
this.route('myaccount', {
path: '/myaccount',
template:'myaccountTemplate',
layoutTemplate: 'layoutTemplate',
data: function() {
...
},
waitOn: function () {
return Meteor.subscribe('...');
}
});
Iron-router-progress is great!
https://github.com/Multiply/iron-router-progress
with this option, it's top
Router.configure
progressDelay : 100

Resources