how to coerce meteor iron:router params to an integer? - meteor

I often have code that forces params to be an integer, i was wondering if there's a better way with IR to handle this frequent case:
#route 'units',
path: "/units/:book?"
name: 'units'
waitOn: ->
book = parseInt(#params.book)
PubSubMan.subscribe "Tiles", {book: book}
This is a pain as the parseInt(#params.book) has to be done in find queries that use the params too, and i also need to guard against non-numbers, etc etc.
Seems that sort of type casting could be a router level option but could't find anything in the docs

Something like
this.route('units', {
path: /^\/units\/(\d+)/
});
Make sure to try with/without last slash in the path and update regular expression to your needs.
You can access parameter with:
this.params[0]

I could not get Roman's suggestion to work, as a regular expression object does not seem to be allowed as a path. I get the error described here:
https://github.com/iron-meteor/iron-router/issues/887
Exception in template helper: Error: Cannot currently resolve a regular expression path
Instead, I found this to be useful: https://github.com/pillarjs/path-to-regexp#custom-match-parameters
In short, I would try the following:
this.route('units', {
path: '/units/:book(\\d+)?'
});
And then you can use this.params.book as you normally would.

Related

iron:router wildcard path generating seems to be broken

When you create a wildcard URL in iron:router for meteor the pathFor Template helper but also Router.go and Router.routes[routeName].path() seems to be broken.
This is our route:
Router.route('/:urlQuery*', function(){
this.render('ourTemplate');
}, {
name : 'ourRoute',
});
To accessing a generated url to this we tried the following:
Router.go('ourRoute', {urlQuery : 'test'});
Router.go('ourRoute', {urlQuery : ['test']});
Router.go('ourRoute', {urlQuery : null});
Router.go('ourRoute', {urlQuery : false});
Router.routes.ourRoute.path({urlQuery : 'test'});
Router.routes.ourRoute.path({urlQuery : ['test']});
Router.routes.ourRoute.path({urlQuery : null});
Router.routes.ourRoute.path({urlQuery : false});
And - of course - also we tried the {{pathFor}} Template-Helper.
Every of these lines of code throw the same errors:
Uncaught Error: You are trying to access a wild card parameter at index 0 but the value of params at that index is undefined
I did not find any reference in the iron:router guide so my question is: How to generate a URL in iron:router with a wildcard as parameter ?
Looks like Iron Router is using path-to-regexp but the format is a little different when used in Iron Router and not very clear. Try this...
Router.route('/:urlQuery(.*)', function(){
The (.) will tell it to take the param name, and repeat it 0 or more times. Just urlQuery is breaking the name I think, and making it part of the regex. Now if you want to pass an array of mulitple objects to Router.go, you will have another issue...
Router.go("our.route", {urlquery: ['test', 'another']});
Produces a URL that looks like this...
http://localhost:3000/test%2Canother
but that's a different issue I don't have an answer for yet. Perhaps for sending multiple's in Router.go, a better way would be to concat them yourself. Looks like iron router and path-to-regexp are not fully integrated yet?

Any chance to use nested Spacebars Tags? (here: Messageformat Package, Autocomplete)

i wond if it's anyhow possible to solve this problem with Spacebars in Meteor:
{{TplVar placeholder="{{mf 'identifier' 'defaultval'}}"}}
This sytnax causes a syntax error.
If the placeholder would not contain spaces - as far as i know - just keeping it free of curly brackets would solve the solutions but this doesn't work here.
I'm a bit at a wall now - should there be really no way to solve it? I've already searched around for jagged handlebars/spacebars template tags but couldn't really find anything useful - especially not for the Meteor context.
Thanks in advance for helping!
Frank
I've never used the Messageformat package (which looks interesting), but from the docs it looks like there's a javascript API. So you can just do something like:
{{TplVar placeholder=thisPlaceholder}}
and
Template.yourTemplate.helpers({
thisPlaceholder: function() {
return mf(this.identifier, this.defaultval);
}
});
Note that I'm assuming identifier and defaultVal are in the data context here - if they're the results from helper functions, you need to replicate those functions within this new thisPlaceholder helper and replace this.identifier and this.defaultval with the results.

Iron:router "globbing" isn't working

I want to be able to match paths like this:
/path/anything/goes/here/and/can/be/an/arbitrarily/long/path.
So I tried all of the following:
Router.route('/path/*', function(){
this.render('home');
});
I also tried the path: '/path/:something(*)' and I also tried specifying the path in the second argument options object to Router.route: {path: '/path/*', action:myActionFunction} along with an action function. I even tried using Router.map instead of Router.route, as prescribed in both of the following:
https://gentlenode.com/journal/meteor-11-iron-router-cheatsheet/18
http://www.manuel-schoebel.com/blog/iron-router-tutorial
But still, going to the /path/anything/goes/here doesn't work. It takes me to the default iron:router error page:
Oops, looks like there's no route on the client or the server for url: "http... localhost:1710... /path/this/should/work/according/to/the/above/links."
Any help is appreciated, thanks.
Try
'/(.*)'
or
'/path/(.*)'
if the url really is domain.com/path/
I serve routes from '/(.*)' via look up on a collection of documents from this.params
If you need any routes prior to a catchall put the catchall route in a Meteor.startup and have your finely grained defined routes prior in your router file client side.
Hope this helps you.

Where did this $ne come from for this find method?

Given the following Meteor code helper from the websites "Try Meteor" tutorial:
// Add to Template.body.helpers
incompleteCount: function () {
return Tasks.find({checked: {$ne: true}}).count();
}
I get pretty much everything about this code except for this arbitrary looking $ne thing. I've seen this before with Meteor examples and I don't get it: What does $ne represent? Where did $ne come from?
$ne means not equal to.
It is preferable to use this instead of {checked: false} since it also includes the ones where the checked attribute isn't in the document {} and the case where {checked: null} as both of these are cases where checked isn't equal to true & are also not false.
This way if you have a fresh document without any attributes it would also be a result of the query.

Router.after is deprecated, is there a replacement global after hook?

I want to change the title of the page after any route has been rendered, to the name of that route. This is the code I was using before:
Router.after(function(){document.title = this.route.name;});
The manual mentions using onAfterAction inside an individual route, but I'd like to do it globally?
You must have missed this : http://eventedmind.github.io/iron-router/#using-hooks
The correct syntax is straightforward :
Router.onAfterAction(function(){
// your hook definition
});
Note : The guide is for iron:router#1.0.0-pre2 which must be added to your app explicitly like this :
meteor add iron:router#1.0.0-pre2
But the Router.onAfterAction works fine in iron:router#0.9.X too.
I suggest using this.route.getName() instead of this.route.name, see more about this issue here :
https://github.com/EventedMind/iron-router/issues/878
The router.after(); method although has been deprecated will still be allowed in the code in terms of syntax. As discussed in the IRC chat the best approach is to use the new syntax.
Router.onAfterAction(function(){
document.title = this.route.name;
});
This should resolve what you are looking for.
Cheers !
Ryan

Resources