Loading
Since we can't guarantee the high speeds of our development environment in production, we need some way to let our users know that our app is loading while data is being downloaded. For example, what if a user clicks on 'Teams' and it takes a couple of seconds for our records to download? It'd be nice if we could show a loading spinner so they know our app is working.
Luckily Iron Router has us covered (from the docs:
"Sometimes you want to wait on one or more subscriptions to be ready, or maybe on the result of some other action. For example, you might want to show a loading template while waiting for subscription data."
To achieve this, we will use the waitOn property in our route. The easiest way to explain what this does is to show you:
both/router.js
Router.configure({
layoutTemplate: 'layout'
});
Router.route('/', {
name: 'games',
waitOn: function(){
return [Meteor.subscribe("games"), Meteor.subscribe("teams")];
}
});
Router.route('/teams', {
waitOn: function(){
return Meteor.subscribe("teams");
}
});
Also make sure you delete client/subscriptions.js
, as we are now subscribing here in our router.
The waitOn
takes a function as a parameter, and returns either one subscription or many in an array. In our 'games' route we subscribe to 'teams' as well as 'games' because when we create a new game we need to be able to pick from a list of teams.
Iron Router now knows to wait for these subscriptions before showing the designated template. But what happens while it's waiting?
Just like setting a layoutTemplate
, we can also set a loadingTemplate
:
both/router.js
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading'
});
...
client/views/loading.html
<template name="loading">
LOADING!
</template>
Now if you look closely while you switch routes you will see the text "LOADING!" appear for a split second.
Let's upgrade our "LOADING!" text to a spinner. For simplicity I'm going to use a package: meteor-spin:
meteor add sacha:spin
client/views/loading.html
<template name="loading">
{{> spinner}}
</template>