First Question
I’m trying to rebuild the Discovering Meteor “Microscope” project using FlowRouter, BlazeLayout and SubsManager, instead of the original Iron Router as a learning exercise. For those of you who haven’t seen it, check it out here https://github.com/DiscoverMeteor/Microscope.
Right now I have the routes for ‘/new’, ‘/best’, and ‘/post/:_id’ but I have a few issues that I’d like some help with
Subs = new SubsManager();
FlowRouter.route('/new', {
name: 'postsListNew',
subscriptions: function(params){
this.register('posts', Subs.subscribe('posts', {
sort: {
submitted: -1,
_id: -1
},
limit: 10
}));
},
action: function (params, queryParams) {
BlazeLayout.render('layout', { content: 'postsList'});
}
});
FlowRouter.route('/best', {
name: 'postsListBest',
subscriptions: function(params){
this.register('posts', Subs.subscribe('posts', {
sort: {
votes:-1,
submitted: -1,
_id: -1
},
limit: 10
}));
},
action: function (params, queryParams) {
BlazeLayout.render('layout', { content: 'postsList'});
}
});
FlowRouter.route('/post/:_id', {
name: 'postPage',
subscriptions: function(params){
this.register('singlePost', Subs.subscribe('singlePost', params._id));
this.register('comments', Subs.subscribe('comments', params._id) );
},
action: function(params, queryParams){
BlazeLayout.render('layout', { content: 'postPage' })
}
});
As you can see, the ‘/new’ and ‘/best’ routes render the same ‘postsList’ template. In the postsList I want to iterate over each post like so
{{#each posts}}
{{> postItem _id=_id}}
{{/each}}
If I’ve registered the posts subscription in the router for ‘/new’ and ‘/best’, how do I hook it up so that “posts” is an array of the posts provided by that subscription? With Iron Router you’d specify
data: function() {
return {
posts: function(){ return Posts.findOne(this.params._id);
}
at the route level and “posts” in the template would already be set to the value of that, what’s the equivalent of doing that with FlowRouter?
I was able to do it with this helper function on the “postsList” template, but then I’m just re-using the same sort and limit options that I used in the router’s “this.register” which seems redundant.
Template.postsList.helpers({
posts: function(){
var options = {};
// sort posts depending on route
if(FlowRouter.current().path.indexOf('new') !== -1){
//new
options = {
sort: {
submitted: -1,
_id: -1
},
limit: 10
};
}else{
//best
console.log('best');
options = {
sort: {
votes:-1,
submitted: -1,
_id: -1
},
limit: 10
}
}
return Posts.find({}, options);
}
});
##Second Question
Using the code above, I’m registering a different subscription (using the same publication but different sort/limit options) for the ‘/new’ and ‘/best’ routes with SubsManager, but if I navigate between them the UI doesn’t re-render with the different data. So if I’m viewing ‘/new’, it shows all the newest posts, but if I navigate to ‘/best’ from there it still shows the newest posts. If I refresh the page on ‘/best’, then it renders with the correct top-voted posts.
If I add a
triggersEnter: [function(){
Subs.clear();
}]
to either of the ‘/new’ or ‘/best’ routes, then it displays correctly when navigating between them but the screen flickers since it appears to be re-fetching the subscription data. Or if I just don’t use SubsManager and use Meteor.subscribe it works, but I’d rather be caching data locally. How do I use SubsManager to cache the data, but still be able to navigate between two routes that use the same publication with different sort options?
Thanks if anyone has already gone through the exercise of rebuilding Microscope using FlowRouter, BlazeLayout and SubsManager I’d love to see your code! If not, I’ll be putting the project up on GitHub when it’s done to help others who are in my shoes.