'Can not read the slug from url on Flow Router (Meteor)

I'm trying to implement a basic route using Flow Router. But no matter what _id of a collection document I request; I always only get the info about the first document in my collection - 'Requests'.

So here's my route definition in the file /lib/routes.js:

FlowRouter.route('/requests/:reqId', {  
  subscriptions: function (params, queryParams) {
    this.register('theRequest', Meteor.subscribe('singleRequest', params.reqId));
  },
  action: function (params, queryParams) {
    FlowLayout.render('layout', { aside: 'aside', main: 'singleRequest' });
    console.log("Yeah! We are on the post:", params.reqId);
  },
  name: 'aRequest'
});

Here's my helper:

Template.singleRequest.helpers({  
    getRequest: function () {
        return Requests.findOne();
    }
});

Here's my server publish:

Meteor.publish('singleRequest', function (reqId) {  
    return Requests.find({ _id: reqId});
});

And here's the template:

<template name="singleRequest">  
  {{#if isSubReady 'theRequest'}}
    {{#with getRequest}}
      <h2>{{_id}}</h2>
      <p>{{reqFrom}}</p>
      <p>{{reqBy}}</p>
    {{/with}}
  {{else}}
    loading...
  {{/if}}
</template> 

What am I doing wrong? Note: In the console, I do see right 'reqId' slug due to the console.log command in the route definition. But I do not see the relevant info for the document which it belongs to.

Thanks!



Solution 1:[1]

OK my problem was that I previously had another subscription where I published all the Requests - not just the one with that certain _id. And because I did not create the helper to get only the one with that certain _id; of course server just sent me the very first request.

My solution was only to subscribe to previous subscription and define in the helper to fetch to the request _id:

FlowRouter.route('/requests/:reqId', {  
  subscriptions: function (params, queryParams) {
    this.register('allRequests', Meteor.subscribe('Requests', params.reqId));
  },
  action: function (params, queryParams) {
    FlowLayout.render('layout', { aside: 'aside', main: 'singleRequest' });
    console.log("Yeah! We are on the post:", params.reqId);
  },
  name: 'aRequest'
});

and the helper:

Template.singleRequest.helpers({ 
  getRequest: function () {
    var reqId = FlowRouter.getParam("reqId")
    return Requests.findOne({_id:reqId});
  }    
});

Solution 2:[2]

For anyone who browses to this question looking for how to get Flow Router to capture and dynamically link to slugs from the db, then call a template page for each item, I made a very simple example app and posted it on here on GitHub.

Hope it will help someone.

Solution 3:[3]

I believe your code is correct for what you are trying to do. However, I infer from your direct replication of the code from flow-router that you're pretty new to Meteor. Therefore, I'm willing to take a punt that you still have the autopublish package in your app.

Autopublish pushes all data in your collection to the client. Even without a publish/subscribe call.

You can do two things. To keep autopublish (which will make your development process easier at the start but maybe harder later on), just change your template helper to:

Template.singleRequest.helpers({  
    getRequest: function () {
        return Requests.findOne({ _id: FlowRouter.getParam("reqId")});
    }
});

Alternatively (and you will want to do this eventually), go the the command line and type:

meteor remove autopublish

You can read up on the pros and cons of autopublish in lots of places to make your own decision on which option is best for you. However, you should also consider whether or not you want to cache your data in future (e.g. using subsManager) so you may want to change your template helper regardless.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Emo
Solution 2 Deborah
Solution 3 Duncan Foster