Reputation: 2065
Here's a rather standard way to set a route in Iron Router:
Router.route('/posts/:_id', {
name: 'postPage',
data: function() { return Posts.findOne({_id: this.params._id}) }
});
Experimenting around a little, beginner as I am, I tried:
Router.route('/posts/:whatever', {
name: 'postPage',
data: function() { return Posts.findOne({_id: this.params.whatever}) }
});
This works well, up to a point. True, whatever
will scoop up whatever is after /posts/
as its value, and the data context will indeed be the same as before... but linking to specific posts now won't work!
So,
<a href="{{pathFor 'postPage'}}">{{title}}</a>
simply won't work doing it "my" way (linking to nothing at all).
I can't fully wrap my head around this, and I'm too much of a novice to grasp the source code for Iron Router, so my hope is that someone here can explain it in a manner that even a beginner like me can comprehend.
Preferably like something like this:
First {{pathFor 'postPage'
}} looks inside the routes to find the one named postPage
.
It sees that this route corresponds to /posts/
followed by something else.
Looking inside the data context it finds that only one post is returned, namely the one with the same _id
as whatever comes after /posts/
.
It understands that it should link to this post, cleverly setting the url to /posts/_id
.
This is wrong, most likely, and it doesn't explain why it would work when whatever
is turned into _id
. But it would help me immensely to see it parsed in a similar fashion.
Edit: Cleaned up my question so it is easier to grasp.
Upvotes: 0
Views: 76
Reputation: 6147
There's a simple set of circumstances that together lead to confusion:
Posts.findOne
issue is explained by the fact that the first argument can be either a selector or a document _id
. So it's not really a shortcut but rather a documented feature.:something
in the iron:router URL causes that value to be reported as this.params.something
inside the route function. This also registers something
as an parameter to that route, which brings us to how pathFor
works.pathFor
helper takes two inputs: first the name of the route (in this case 'postPage'
) and second an object of parameters, which can come either from the second argument as in {{pathFor 'postPage' params}}
or from the data context like so: {{#with params}}{{pathFor 'postPage'}}{{/with}}
.Now, here's why passing in a document from the database works if you call the parameter _id
but not if you call it whatever
: the post object that you retrieved from the database _has an _id
field, but it doesn't have a whatever
field. So when you pass it into pathFor
, it only passes along the correct _id
if the parameter to the route also happens to be called _id
.
Let me know if that makes sense, I agree that this is somewhat confusing and that this "shortcut" hides what exactly pathFor
and params
actually do.
Upvotes: 1