The Iron Router / Meteor examples all seem to use _id
in the named routes, which works. However, I am missing something in order to use a named route from another key in a collection other than _id
. Specifically, I am using the tag
key.
'/tags' route
This tag list route works as expected: http://localhost:3000/tags
Router.route('/tags', {
name: 'demoTagsList',
waitOn: function() {
return Meteor.subscribe('tags');
},
data: function() {
return Tags.find();
}
});
The pathFor
for demoTagItem
works as expected
<a href="{{pathFor 'demoTagsList'}}">Tags</a>
As does Router.routes['demoTagsList'].url()
--> "http://localhost:3000/tags"
'/tags/:_tag' route
This specific tag route also works as expected and returns the appropriate data: http://localhost:3000/tags/foo-tag
Router.route('/tags/:_tag', {
name: 'demoTagItem',
waitOn: function() {
return Meteor.subscribe('itemsFromTag', this.params._tag);
},
data: function() { return Posts.find({tags: this.params._tag}); }
});
However, the pathFor
for each demoTagItem
route results in null
.
Router.routes['demoTagItem'].url()
--> "http://localhost:3000null"
The template code:
<template name="demoTagsList">
<h2>Demo Tag list</h2>
<ul>
{{#each tags}}
<li class="tag"><a href="{{pathFor 'demoTagItem'}}">#{{name}}</a></li>
{{/each}}
</ul>
</template>
What needs to happen to set the router path so that pathFor
picks up {{name}}
and builds the link as tags/tag-name
?
If you have a look at the pathFor docs you'll see that the function requires a data
context to fill in the parameters in the route. You can explicitly set the data
with a template helper like so:
<li class="tag"><a href="{{pathFor 'demoTagItem' data=getTag}}">#{{name}}</a></li>
where getTag
is a template helper that returns an object like {_tag: 'puppies'}
.
However, the path of least resistance is often to set the route params to have the same field name as a tag object would natively. Assuming your tags have a name
property, you could modify your route like this:
Router.route('/tags/:name', {
name: 'demoTagItem',
waitOn: function() {
return Meteor.subscribe('itemsFromTag', this.params.name);
},
data: function() { return Posts.find({tags: this.params.name}); }
});
Now your template shouldn't require any modifications from the original code because the context is already a tag. That should be the equivalent of writing data=this
where this
looks like {name: 'puppies'}
.