Comments (22)
Hey @awatson1978, I haven't read through your entire post yet (sorry if I'm missing something), but there was a bug matching paths with query params that @tmeasday fixed. It's part of the latest release that I just released a second ago. Can you update the package (0.5.4) and let me know if the problem persists?
from iron-router.
Awesome! Will do! :)
from iron-router.
So, just updated to 0.5.4, and the issue still seems to be there. Can't seem to parse parameters. :(
As a quick aside, would this be the correct way to inspect and log parameters? You mentioned this callback near the bottom of the Iron-Meteor documentation, so it might be a good start to simply confirm this is the right way to access the parameters object?
this.route('template', { }, function(){
console.log(this.params);
}
);
from iron-router.
Hmm, bummer. Okay @awatson1978. Give me a bit and I'll take a closer look.
from iron-router.
I have the same error that Abigail reported. I just tested with the latest version (0.5.4) and the error is still there.
Abigail, yes you can access the params with the example code you posted. You can also access the path thus:
Router.path('routeName');
Also, inside the template. I have to look this up again, I forgot it :)
And of course you can use a Controller, as in:
customController = RouteController.extend({
customAction: function () {
console.log(this.params);
}
});
from iron-router.
Oh my goodness I should have read your entire post @awatson1978. I parsed it quickly and tried to respond with the closest association I could make (that we originally had a query params matching issue). Sorry! So let me walk through the way it should work. Let me know if these changes/explanations help:
Query parameters don't need to be specified in your route path. They are always variable. But they should be accessible in the params object inside your handler. I'll give a few examples below, one using a direct route handler, and another using a RouteController.
Example 1: Direct route handler for smaller apps
Router.map(function () {
this.route('stripeRedirect', {
path: '/stripe'
}, function () {
var code = this.params.code; // if code is passed as a query parameter in the path, it should be accessible here.
});
});
Example 2: Using a RouteController - An anonymous RouteController is created in example 1. So it's actually the same thing, except here we're creating an explicit RouteController instance.
Router.map(function () {
// note you can change the controller name by providing a controller option. and you can
// change the default 'run' action by providing an action option.
this.route('stripeRedirect', { path: '/stripe' });
});
StripeRedirectController = RouteController.extend({
run: function () {
var code = this.params.code;
}
});
So this.params
is available inside any RouteController instance. Does this make sense and/or help?
EDIT: Some more examples using query parameters => this.params.
given: '/path?firstParam=one&secondParam=two
this.params.firstParam => "one"
this.params.secondParam => "two"
But you don't need to specify firstParam
or secondParam
in your path
option for the route. You can provide any number of query parameters (keys and values) and it will still match the route.
from iron-router.
Ah! Okay, so that makes a lot of sense. And, yes... got access to some parameters now! :)
So, definitely making some progress. Here's what I'm seeing/experiencing after trying those code suggestions:
Router.map(function () {
//this takes me to the stripeRedirect template, but has no access to parameters
this.route('stripeRedirect', {
path: '/stripe'
});
//this writes the parameters to the console, but doesn't redirect to the stripeRedirect template :(
this.route('stripeRedirect', {
path: '/stripe'
}, function () {
console.log('stripe.code: ' + this.params.code);
console.log('stripe.scrope: ' + this.params.scope);
});
//this doesn't work either, so it's not some obscure blocking issue with console logging
this.route('stripeRedirect', {
path: '/stripe'
}, function () {
//console.log('stripe.code: ' + this.params.code);
//console.log('stripe.scrope: ' + this.params.scope);
});
});
// this doesn't redirect to the stripeRedirect template either :(
// but it does write parameters to the console! :)
StripeRedirectController = RouteController.extend({
run: function () {
//var code = this.params.code;
console.log('stripe.code: ' + this.params.code);
console.log('stripe.scope: ' + this.params.scope);
//Router.go('stripeRedirect');
}
});
from iron-router.
Almost there. Now you need to tell the controller what to render. So inside your action function you can call this.render('templateName'); as the last line. You can call this.render() without a template name if the template is defined as a property on your controller, or if the route name is the same as the template name.
from iron-router.
Ah! That did the trick! :)
Final code was the following, for anybody else who's trying to do something similar. Maybe an OAuth example is worth going in the docs?
//---------------------------------------------------------------------------------------------------------------------
// OAuth Configuration
// specify the URL redirect route as part of the OAuth setup
localhost:3600/stripe
// the oauth authentication process will redirect users to that URL with parameterized tokens
localhost:3600/stripe?scope=read_only&code=ac_2QGZP0nOBmb0Lxk9q3pMzaRvOi4fMU8j
// so the Router needs to access the scope and code parameters
?scope=read_only&code=ac_2QGZP0nOBmb0Lxk9q3pMzaRvOi4fMU8j
//---------------------------------------------------------------------------------------------------------------------
// Iron Router Configuration
// create the route like normal; the parameters will be automatically parsed
Router.map(function() {
this.route('stripeRedirect', { path: '/stripe'});
});
// and extend the controller, so you can access the this.params object
StripeRedirectController = RouteController.extend({
run: function () {
// the code parameter has been automatically parsed and is available for use
console.log('stripe.code: ' + this.params.code);
// as is the scope parameter
console.log('stripe.scope: ' + this.params.scope);
// when all this is done, be sure to render the template specified in the router map
this.render('stripeRedirect');
}
});
from iron-router.
An OAuth example in the docs would be a great idea. If you have the time for a PR that would be awesome. But I'll also be doing another pass over the README this weekend.
from iron-router.
Hi guys,
The README.md file gives an example for URL routing that looks like this (what @awatson1978 demonstrated in her first post):
Router.map(function() {
this.route('showPost', {
path: '/posts/:_id',
data: function() { return Posts.findOne(this.params._id); }
});
});
When I run this same code (just different template and collection names substituted, as well as a log for reference), I receive the same uncaught _id error that @awatson1978 was receiving.
My code:
Router.map(function() {
// Home page
this.route('home', {path: '/'});
this.route('home', {path: '/home'});
// Create/Edit page
this.route('edit', {
path: '/edit/:_id',
data: function() {
console.log(this.params);
return Polls.findOne(this.params._id);
}
});
});
And when I visit http://localhost:3000/edit/12345, my console shows:
[_id: "12345"]
As well as the error:
Exception from Deps recompute: Error: _id not found in params
at http://localhost:3000/packages/iron-router.js?2f848a70f81fa257705f5ffa213d4eb31759e02d:493:21
at String.replace (native)
at RoutePath.resolve (http://localhost:3000/packages/iron-router.js?2f848a70f81fa257705f5ffa213d4eb31759e02d:482:10)
at Route.path (http://localhost:3000/packages/iron-router.js?2f848a70f81fa257705f5ffa213d4eb31759e02d:714:30)
at IronRouter.path (http://localhost:3000/packages/iron-router.js?2f848a70f81fa257705f5ffa213d4eb31759e02d:1087:35)
at Object.<anonymous> (http://localhost:3000/packages/iron-router.js?2f848a70f81fa257705f5ffa213d4eb31759e02d:2405:19)
at apply (http://localhost:3000/packages/handlebars.js?c2b75d49875b4cfcc7544447aad117fd81fccf3b:276:24)
at invoke (http://localhost:3000/packages/handlebars.js?c2b75d49875b4cfcc7544447aad117fd81fccf3b:301:12)
at http://localhost:3000/packages/handlebars.js?c2b75d49875b4cfcc7544447aad117fd81fccf3b:365:30
at Object.Spark.labelBranch (http://localhost:3000/packages/spark.js?3a050592ceb34d6c585c70f1df11e353610be0ab:1171:14)
I checked to make sure I was running the right version, as @cmather said, and I am indeed running v0.5.4.
I just wanted to let you know that the issue may not actually be fixed.
Before running the example, though, I updated the meteor proj to v0.6.5.1 (just released today I think)--I'm not sure if that could be playing a roll.
All this being said, I'm very new to meteor and iron-router, and I could totally be making a mistake here. Please forgive me if I am.
from iron-router.
Hey @maxspad, I just tried out creating the same edit path you have above. It worked okay for me, so maybe there's something else going on here. Also note, you have two routes that have the same name "home". Each route should have its own unique name. I'll enforce this in the next version of the router.
Can you paste your exact routing file or create a Githhub reproduction of the error you're seeing?
If you have a route like this:
Router.map(function () {
this.route('edit', {
path: '/edit/:_id',
data: function () {
console.log(this.params._id);
return SomeCollection.findOne(this.params._id); // might return null if data not loaded yet
}
});
});
// path: /edit/1234
// console: > 1234
from iron-router.
The above example assumes you have a template named "edit" defined.
from iron-router.
So, as a bit of feedback, the way the docs are currently written makes this seem like the recommended approach, which is what both I and maxspad tried to do:
this.route('home', {path: '/'});
this.route('home', {path: '/home'});
The problem, I think is the following line:
By default the name of the route (the first argument to this.route()) is also the name of the template to be rendered by this route.
Which, on a naive first reading, seems to imply the following:
this.route('templateName', {path: '/'});
this.route('templateName', {path: '/home'});
That's what people are trying to do. Instead, if I understand the pattern correctly, they should be trying to do the following:
this.route('route_name_a', {path: '/', template: 'templateName' });
this.route('route_name_b', {path: '/home', template: 'templateName' });
from iron-router.
Yeah I think you're right. I need to update that readme ASAP. I'm circling back to this project later in the week and I'll pull in your PR and do some additional readme cleanup.
from iron-router.
Thanks guys--That's exactly what had me confused.
from iron-router.
One more update - I found the root cause of my _id not found error.
After a bit of experimentation, I found that traveling to any address in my app routed to a template which included a {{pathFor 'edit'}}
('edit' being the route I was having trouble with before) gave the _id not found error--even if the pathFor
was the href of a link that wasn't ever clicked. I haven't had enough of a chance to dig into the source and look behind the scenes as to what is going on, but it seems to me that pathFor
actually makes a call to Router.path
without any parameterizing data when it is rendering the path string (which makes sense, as no parameters are provided to it), and it is Router.path
that throws the error in the process of rendering the path string rather than while actually changing the active template.
I would have expected clicking on the link (and therefore initiating the template transfer) to generate the error, but the hidden (though logical and apparent now) call to Router.path threw me off.
Thanks very much for your help!
Max
from iron-router.
Oh okay that makes sense. The path helpers produce an actual path string so get evaluated at template render time. The error message should be a lot better.
Sent from my iPhone
On Aug 28, 2013, at 8:45 PM, maxspad [email protected] wrote:
One more update - I found the root cause of my _id not found error.
After a bit of experimentation, I found that traveling to any address in my app routed to a template which included a {{pathFor 'edit'}} ('edit' being the route I was having trouble with before) gave the _id not found error--even if the pathFor was the href of a link that wasn't ever clicked. I haven't had enough of a chance to dig into the source and look behind the scenes as to what is going on, but it seems to me that pathFor actually makes a call to Router.path without any parameterizing data when it is rendering the path string (which makes sense, as no parameters are provided to it), and it is Router.path that throws the error in the process of rendering the path string rather than while actually changing the active template.
I would have expected clicking on the link (and therefore initiating the template transfer) to generate the error, but the hidden (though logical and apparent now) call to Router.path threw me off.
Thanks very much for your help!
Max—
Reply to this email directly or view it on GitHub.
from iron-router.
What about when you need to instantiate a template's variable within the data object?
Example:
this.route('items', {
path: '/items/:_type',
template: 'items',
data: {
templatevariable: function() {
console.log(this.params._type); //<--- HERE -- this returns 'undefined'
//return ItemList.find('type':this.params._itype);
}
}
});
The params never get passed (undefined) and I can't wrap the above in a function
from iron-router.
Just a quick update -- got it to work, but I had to set a Session variable to carry it forward. Seems unnecessary, IMO.
this.route('items', {
before: function() {Session.set('ItemType',this.params._type);},
path: '/items/:_type',
template: 'items',
data: {
itemlist: function() {
return ItemList.find({'type':Session.get('ItemType')})
}
}
})
from iron-router.
@FusionAge, Just make your data value a function. You'll have access to the params property in there. Like this:
this.route('items', {
path: '/items/:_type',
data: function () {
var type = this.params._type;
return {
itemList: function () { ... }
};
}
});
from iron-router.
I am using router.go to route to a path . I am giving parameters inside the query object of router.go .
The problem is the parameters are adding along with the url , which is not desirable in my case .
Router.go('smsVerification', {foo:'bar'}, {query: queryData,foo3:'bar3'},{fooNew:'barNew'});
this.route('smsVerification', { name: 'smsVerification',path: '/smsVerification',data:function(){
return {
mobileNo: this.params.query.mobile_no
};
}});
what can i do for sending parameters in router.go and the parameters should not be shown in the url.
from iron-router.
Related Issues (20)
- abort unload HOT 1
- Meteor, Iron router: Render makes the page to shake
- Parameters can't have *s in them
- post to serverside route forces client to the posts action url HOT 1
- undefined routes terminate web socket connection
- Iron router Issue with spiderable HOT 4
- can be read from a controller, variables from another controller?
- Defining routes using arrow functions doesn't work HOT 1
- Path name with '/' inside it... HOT 1
- Request entity too large error
- Errors prevented startup: W
- meteor iron:router not working HOT 1
- Dynamic Imports with Iron Router HOT 10
- Able users to save audio files for offline viewing HOT 2
- How to use pathFor have id like {{pathFor route='index.resource.show'}}/{{data._id}} HOT 2
- Subscription lost after a few minutes HOT 1
- Supporting newer versions of Meteor with compat packages
- ERR_OUT_OF_RANGE
- why async, promise?
- Source for iron-router 1.2.0? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from iron-router.