Jamgreen
Jamgreen

Reputation: 11039

Get parameters from router with Meteor and iron:router

I have a route

Router.route('/post/:_id', {
  name: 'post',
  template: 'post'
});

and a helper

Template.post.helpers({
  post: function () {
    return Posts.findOne(this._id);
  }
});

It wont find the specified post. But I guess I'm getting the id in a wrong way. I've seen some projects where they have used sessions. Is this really necessary? Isn't it possible to get the parameters from the router?

Upvotes: 3

Views: 1888

Answers (2)

atulmy
atulmy

Reputation: 1383

It is more organized to have all your data fetching points in helpers. So you can do this:

routes.js

Router.route('/post/:_id', {
    name: 'post',
    template: 'post'
});

post.js

Template.post.helpers({
    post: function() {
        var postId = Router.current().params._id;
        return Posts.findOne({_id: postId});
    }
});

Remember that if you are not subscribing (posts) in any other file, you can subscribe in router itself:

routes.js (with subscription)

Router.route('/post/:_id', {
    name: 'post',
    template: 'post',
    waitOn: function() {
        return Meteor.subscribe('posts');
    }
});

Update:

Router.current().params._id seems to have an issue, it'll return all the Id's for that route previously ran.

So restructured way should be (example from my app):

route.js

Router.route('/play/:gameId', {
    name: 'play',
    template: 'gamesPlay',
    waitOn: function() {
        return Meteor.subscribe('games');
    },
    onBeforeAction: function() {
        Session.set('gameId', this.params.gameId);
        console.log('game id set '+Session.get('gameId'));
        this.next();
    },
    onStop: function() {
        // do something when user navigate away from this route
    }
});

games.js

Template.gamesPlay.helpers({
    game: function() {
        var gameId = Session.get('gameId'); //instead of Router.current().params.gameId;
        var game = Games.findOne({_id: gameId});
        return game;
    }
});

Upvotes: 0

saimeunt
saimeunt

Reputation: 22696

Usually you'd set the data context at the route level like this :

Router.route("/post/:_id",{
  name:"post",
  template:"post",
  waitOn:function(){
    return this.subscribe("post",this.params._id);
  },
  data:function(){
    return Posts.findOne(this.params._id);
  }
});

In RouteController methods you can access the URL parameters using this.params.parameterName.

Then in your post template you can access the data context set by the router without the need of a dedicated helper.

<template name="post">
  post id is {{_id}}
</template>

As far as the posts list is concerned, you can stick to the same pattern :

Router.route("/posts",{
  name:"posts",
  template:"posts",
  waitOn:function(){
    return this.subscribe("posts");
  },
  data:function(){
    return {
      posts:Posts.find()
    };
  }
});

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

Upvotes: 3

Related Questions