When I start the Meteor server and navigate to my default route, I see the AppLoading template inside MainLayout (as expected), but the main template never loads even after the subscription is loaded.
I've got a really simple routes.js file (below)
autopublish is still turned on.
I seeded the db and can confirm in the browser console that the subscription is there, and there are items in my Services collection.
Probably missing something really simple here.
/*===================
CONFIGURE DEFAULTS
====================*/
Router.configure({
layoutTemplate: 'MainLayout',
loadingTemplate: 'AppLoading',
notFoundTemplate: 'NotFound'
});
/*===================
CONFIGURE ROUTES
====================*/
Router.route('/', { // DEFAULT ROUTE
name: 'main',
template: 'Main',
waitOn: function() {
return Meteor.subscribe('services');
},
data: function() {
return Services.find();
}
});
I'm guessing you do not have a publication? The client is waiting for a "ready" notification from the publication and is not receiving it, hence nothing is loaded. Remove autopublish and start writing publications.
The autopublish package literally just copies the server DB to the client. You can't subscribe to anything if you do not actually have any publications.
Related
Does iron router have an event when the Meteor app is loaded?
I would like to run a function when template 'loading' is display, and when app is loaded.
To display a template while loading put this line in the router file.
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading'
});
where loading is the loading template.
Alternatively: pcel:loading package from atmospherejs.
Router Hooks:
You can try to use the router hooks provided by iron-router such as waitOn, onBeforeAction etc. in conjunction with your loading template.
For example:
If you have a route named path and a subscription named foo being accessed on that route:
Router.route('/path', {
// this template will be rendered until the subscriptions are ready
loadingTemplate: 'loading',
waitOn: function () {
// perform action while database subscription loads
console.log('Fetching foo...');
return Meteor.subscribe('foo');
},
onBeforeAction() {
// perform action before route loads
console.log('Loading...');
this.next();
},
action: function () {
// perform action when route loads
// ...
this.render('myTemplate');
},
onAfterAction() {
// perform action after route loads
// ...
}
});
From the official guide, there are a number of options available to perform functions at router level, depending on exactly when you want the action to initiate:
Available Hook Methods
onRun: Called when the route is first run. It is not called again if the route reruns because of a computation invalidation. This
makes it a good candidate for things like analytics where you want
be sure the hook only runs once. Note that this hook won't run
again if the route is reloaded via hot code push. You must call
this.next() to continue calling the next function.
onRerun: Called if the route reruns because its computation is invalidated. Similarly to onBeforeAction, if you want to continue
calling the next function, you must call this.next().
onBeforeAction: Called before the route or "action" function is run. These hooks behave specially. If you want to continue calling
the next function you must call this.next(). If you don't,
downstream onBeforeAction hooks and your action function will not
be called.
onAfterAction: Called after your route/action function has run or had a chance to run. These hooks behave like normal hooks and
you don't need to call this.next() to move from one to the next.
onStop: Called when the route is stopped, typically right before a new route is run.
Plugins:
If you want to reuse the same functionality on multiple routes, you can create route plugins like this:
Iron.Router.plugins.loading = function (router, options) {
// this loading plugin just creates an onBeforeAction hook
router.onBeforeAction('loading', options);
};
Take a look at the full guide to try more hooks and methods that may be useful to you.
I recently updated my meteor project and whenever i try to run my project i got this :
Router.route('/', function () {
this.render('Home', {
data: function () { return Items.findOne({_id: this.params._id}); }
});
});
this is my route that should direct the user to "main" template
Router.route('/', {
template: 'main'
});
i used to get similar problem when i first added iron:router package, and the reason was because i haven't implemented it. I believe the way i should implement it is different after the update. please correct me if am wrong
Your router file needs to be included above or in a folder above your client and server folders. It's just there, if router is not contained above client and server than meteor does not digest it properly for the function it serves.
Short answer:
Put router.js where-ever it is that you start your meteor application.
(as opposed to .\client or .\server)
How you configure main template:
Router.configure({
layoutTemplate:'yourMainTemplateName' //main template should have {{> yield}} inside HTML which tells iron:router where to render templates per route
});
Route configuration:
Router.route('/', function () {
this.render('homeTemplateName');
});
Update your question with your new codes if it doesn't work.
Current we are using a meteor App with the iron:router package and also the spiderable and phantomjs for making this app crawlable by google.
In our special case we have some Routes where we call Meteor methods which are running async before we render the right template into our layout.
When testing spiderable on these routes the template will never get rendered and instead our "loading" template will be the rendered template.
We are testing this with /?_escaped_fragment_=
Now we are looking for a solution to tell spiderable that the page is ready or is not ready so we can control when the page has to be rendered.
Router.route('/awesome-route', function(){
// This is how it could look to tell spiderable that it has to wait
Spiderable.pleaseWait();
// Render the loading template until our route is ready
this.render('loading');
// Waiting for the response of our method
Meteor.call('data', function(err, resp){
this.render('awesome', {
data : resp
});
// This is how it could look to tell spiderable we are ready / always be polite
Spiderable.thanksForWaiting_WeAreReady();
});
}, {
name : 'awesome'
});
When opening now localhost:3000/awesome-route?_escaped_fragment_= we will just see the laoding template ...
The other option for us would be: Is there any alternatives for getting meteor apps crawled by google yet ?
Since spiderable will pre-render your template using phantomjs on server, there is no need for special methods like spiderablePleaseWaitForALittleBitMore_Please
You can just say to your iron:router that template is not rendered yet. Use onBeforeAction hook:
Router.route('/awesome-route', {
name : 'awesome',
template: "awesome",
loadingTemplate: "loading",
onBeforeAction: function(){
var next = this.next;
Meteor.call('data', function(err, resp){
next();
});
}
});
I would like to change the splash message of Iron Router failure .Instead of "Organize Your Meteor Application" ,add something user friendly.How to start with this issue ??
It is hard coded here in iron:router repo.
You can fork it and change this line to yours.
But why do you need this? Line 54 here can give you the idea of how iron:router uses your templates.
Router.prototype.lookupNotFoundTemplate = function () {
if (this.options.notFoundTemplate)
return this.options.notFoundTemplate;
return (this.routes.length === 0) ? NO_ROUTES_TEMPLATE : DEFAULT_NOT_FOUND_TEMPLATE;
};
Only if you don't have any routes defined and no config for notFoundTemplate, you will see such message, define it via router config.
Router.configure({
layoutTemplate: 'layout',
notFoundTemplate: 'pageNotFound'
});
Yesterday I updated meteor and my meteorite packages to their latest versions. Today, iron router is not behaving. When I navigate to a parameterized route, the parameter is not loaded. What gives? I have looked at the documentation for iron-router, and it still specifies the same scheme I was using before.
This is the routes file I have created
Router.map(function() {
this.route('home', {
path: '/'
});
this.route('list', {
path: '/:_id',
waitOn: function() {
return Meteor.subscribe('lists')
},
data: function() {
var list = Lists.findOne({
_id: this.params._id
});
Session.set('listId', list._id);
return list;
}
});
});
When I load a page to http://localhost/1234 the path in iron router is correctly set to /1234 but it does not recognize the last bit as a parameter.
I am afraid that what is empty is not your this.params object but rather the list document, at least for the first time the route is being executed. This is caused, of course, by the latency related to fetching server data.
You may be thinking that it shouldn't happen because you have used the waitOn hook. But for this to work you would also need to do two other things:
Router.onBeforeAction('loading');
and define the loading template:
Router.configure({
loadingTemplate: 'someTemplateName'
});
so please update if you haven't done it already.