Search code examples
javascriptmeteormeteor-blazespacebarsflow-router

Meteor Flow Router setting up example.com/singlePostPage


I can not manage to create the routes to show a single post with flowrouter and blaze in Meteor.

This is what I have so far which I am sure its mostly wrong!

publications.js

Meteor.publish('singlePost', function (postId) {
  return Posts.find({ _id: postId });
});

Router.js

FlowRouter.route("/posts/:_id", {
    name: "postPage",
    subscriptions: function (params, queryParams) {
     this.register('postPage', Meteor.subscribe('singlePost'));
 },
    action: function(params, queryParams) {
        BlazeLayout.render("nav", {yield: "postPage"} )
    }
});

singlePost.JS

Template.postPage.helpers({
  thisPost: function(){
    return Posts.findOne();
  }
});

singlePost.html

<template name="postPage">
  {{#with thisPost}}
    <li>{{title}}</li>
  {{/with}}
</template>

I used to do it back then with Iron router but now got confused with Flow router.


Solution

  • First don't use the FlowRouter subscriptions. That will soon be deprecated. Use Meteor PubSub. First in the routes.js:

        // http://app.com/posts/:_id
        FlowRouter.route('/posts/:id', {
            name: "postPage",
            action: function(params, queryParams) {
                BlazeLayout.render("nav", {yield: "postPage"} )
            }
        });
    

    Then when the template is created you subscribe using Meteor's subscription:

    // Template onCreated
    Template.postPage.onCreated(function() {
        // Subscribe only the relevant subscription to this page
        var self = this;
        self.autorun(function() { // Stops all current subscriptions
            var id = FlowRouter.getParam('id'); // Get the collection id from the route parameter
            self.subscribe('singlePost', id); // Subscribe to the single entry in the collection with the route params id
        });
    });
    

    Then the helper will be:

    // Template helper functions
    Template.postPage.helpers({
        thisPost: function() {
            // Get the single entry from the collection with the route params id
            var id = FlowRouter.getParam('id');
            var post = Posts.findOne({ // Get the selected entry data from the collection with the given id.
                _id: id
            }) || {};
            return post;
        }
    });
    

    You also need to check if the subscriptions are ready in html.

    {{#if Template.subscriptionsReady}}
        {{#with thisPost}}
            <li>{{title}}</li>
        {{/with}}
    {{else}}
        <p>nothing to show</p>
    {{/if}}