iron:router wildcard path generating seems to be broken - meteor

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?

Related

next.js - dynamic route consisting of multiple slugs?

Is it possible to structure a route that contains dynamic parts in predefined format, such as /[name]-id[id], for example to have routes /bob-id303 or /mary-id205?
What I tried is create a file [name]-id[id].js. Inside getInitialProps I console.log the ctx and it contains
pathname: '/[name]-id[id]',
query: { 'name]-id[id': 'bob-id303' },
asPath: '/bob-id303',
On the other hand, calling the file [[name]]-id[id]].js gives
Failed to reload dynamic routes: Error: Optional route parameters are not yet supported ("[[name]-id[id]]").
I'd like to get the name and id directly, then pass them through initial props to the page. I'm aware I can parse asPath, but is there another way to do this?
You could use /[slug] and then do slug.split("-id"). However you may be better off doing the id alone followed by a fetch for metadata because the name could change and then that url would potentially 404.

Ironrouter says route doesn't exist when it does ("Oops, looks like there's no route on the client")

I am trying to display a URL with a paramter in Meteor like so:
http://localhost:3000/test/123
My routes.js contains the following:
Router.route('/test/:x1', function () {
this.render('test', {
to:"main",
param:this.params.x1
});
});
and main.html the following template
<template name="test">
<h2>Test {{param}}</h2>
</template>
However, when I access http://localhost:3000/test/123 I get the following error message:
Oops, looks like there's no route on the client or the server for url:
"http://localhost:3000/test/123."
I have pretty muched copied this verbatim from the ironrouter docs. Other issues Stackoverflow, like Meteor deploy Iron:Router "oops looks like there's no route on the client or the server for url" does not seem to address exactly this issue
So I solved the problem in a somewhat inconclusive way. As was pointed out by one of the commentors, the code in itself works, but not in my application. So I created a new application and transferred the code, line by line, to the new application, and it kept on working. Not all the code was displayed above, but the parts that were omitted should not have affected this problem. I still don't know though what triggered the problem in the first place.

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

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.

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.

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