Search code examples
performancemeteorroutesiron-routerspacebars

Should I Provide Data In Routing Logic or Meteor Template Helper?


Example:

I am writing a Meteor app that deals with a list of blog posts. All blog posts are stored in a collection called 'Posts'. I use Iron Router for routing.

I want to show the user a list of all the posts created by a particular author. This list will be displayed using Spacebars. Therefore, I need to provide the data to the template.

Problem:

As far as I know, there are two ways to do this:

  1. Using template helpers
  2. Using the 'data'-property of my route

Option 1 example:

Template.postList.helpers({
postsToDisplay: function(){
    return Posts.find({author: 'someAuthor'});
}
})

Option 2 example:

//Inside my route
data: function(){
    return {postsToDisplay: Posts.find({author: 'someAuthor'})};
}

Question

Are there any significant differences between those two methods? Is there a reason to prefer one over the other? Does one deliver better performance?

Thank you very much for your answers!


Solution

  • Are there any significant differences between those two methods? Does one deliver better performance?

    Not really, it's just design choices after all.

    Is there a reason to prefer one over the other?

    I would stick to the iron-router + data method, here is why :

    • You can use waitOn to actually display the list only when data fetched from the server is ready, using Router.onBeforeAction("loading") and a loadingTemplate improves overall user experience.

    • You can design a data agnostic postsList template that you can feed with different contexts.

    The last point is particularly interesting, because it allows you to define a reusable template that you could use to display the list of recent posts, the list of posts in a category, the list of posts by a certain author as you want to achieve in the first place, etc...

    <template name="postsList">
      {{#each posts}}
        {{> postListItem}}
      {{/each}}
    </template>
    

    Here you could define posts as a helper of postsList, but it's better to let the parent template that will call postsList assign posts to whatever it needs to.

    template:"postsList",
    data:function(){
      return {
        posts:Posts.find({
          "author":this.params.author
        })
      };
    }
    

    This design pattern allows us to define a route that provides a data context which represents the list of posts by a given author, but you could also define another route providing a data context which will list posts by category.

    So by moving out the data provider role from the template helper to the route definition, we have a much more reusable template, which is nice.