-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
transitionTo with params #175
Comments
In your state definition, a url property doesn't contain any parameters. Try add one: .state('clients.prospects', {
url: '/prospects/:id',
templateUrl: 'views/clients/prospects/prospects.html',
controller: 'ProspectsCtrl'
}) Then, you can access it in this way: console.log("ProspectsCtrl StateParams: ", $stateParams.id) Parameters that are not defined are not passed to If you want this parameter to be optional, check issue number #108. However, the trailing slash must be included. |
Thanks for the rapid response! I really appreciate you taking the time. Does that mean that I can't add anything to the state which is not included The url doesn't see to be the ideal place to store application state for an I'm still trying to get my head around Angular and ui-router, so any Thanks again. On 14 June 2013 11:40, Adam Babik notifications@github.com wrote:
Keith Garrod Tel: +27-83-3000-988 |
You're welcome. That's what Github is, not only a tool to share open source code, but also a platform to post issues, discuss ideas and so on. ui-router has helped me a lot so now I'd like to help the community answering questions :) I'd like to notice that I'm not a guy from the angular-ui team so take my explanation with a pinch of salt. I'm following the project just for about a month.
Actually, you can but it's a bad idea. You have an access to the state configuration in this way: If you want to keep some additional stateless data, which is not connected with the URL and is gone after refreshing the page, you may want to create custom service. See http://docs.angularjs.org/api/AUTO.$provide#service. ui-router is a library to handle navigation and UI of your app. It works closely with the URL of a page and changes UI when the URL changes. It's like you go to a new place and ui-router changes the surroundings.
It helps in this way that it figures out which view should be displayed, which resources should be retrieved and which controller should be run. Hence, the URL must have enough information to do that and it must be unambiguous. Ask yourself a question what user should see if he types Hope it clears things up. |
There is a way to specify params without URL. It's not documented and needs to be. Pretty sure it's a |
It would be nice to use transitionTo to define parameters that aren't necessarily in the url, though. It just makes sense. |
At present, you can either define parameters in the url or by using the params array, but not both. In fact, if you specify a params array, your state can't have a url at all. States that can't be accessed by url are good for cases where the user is in the middle of a workflow and the application is controlling the state transitions. If you do this, the state will still have access to the parameters of its ancestors, so if you want to put additional parameters into mix during a workflow, you can define a child state that has those parameters and transition into it with transitionTo. The parameters that came from the urls (or params arrays) of the ancestor states will still be in $stateParams. |
Hm I suppose having "hidden" parameters in addition to the "static" (currently implemented) and "dynamic" (planned) parameters could make sense. Even though I'm not entirely sure what you'd use them for -- essentially they'd all lose their values when the state gets reloaded from a URL. |
What about "previousUrl" when redirecting to a login view? (I really disagree with the argument that every single page app should have a modal to let users log in). I use the rootScope as a dirty hack right now. |
I too don't like to play good cop/bad cop with authorization and routing in the state machine itself. It's easier if the right service interjects itself when the time comes when the user isn't authorized to do something. Enter angular-http-auth . If you start from the premise that if you can't retrieve it from the server unless you're authorized by the server, then this module may come in handy. If you use it, you have the opportunity to inject a workflow through an event that pops out at the app. The event gives you a chance to supercede everything that's going on in your ui to handle the need to log in, and then retries the requests that started the request. I think it's a great leg up on using server-side security while providing the most important hooks to the client in order to prompt a login. I think with a little tweaking to default behaviors and some options being made configurable, that angular-http-auth is a really valuable asset.
I've thought about having some sort of "preconditions" support in a router. Essentially it would be $state allowing for subroutines of login-type things to take place, still using the service, and then pick up where it left off. Essentially queuing the original request behind the preemptive routing that is necessary to meet one or more of the preconditions). As it stands, $state tries to shrug off requests that are pre-empted by newer events that trickle down from the $location service, in favor of completing their transitionTo() processes as they are called. I recall that @jeme has some additional support for the transition aspects of the state machine in https://github.com/dotJEM/angular-routing ... |
I looked at angular-http-auth but haven't used it since it didn't provide me with the bulk of what I needed (essentially a client-side redirect to login page and redirect back to original) and since I am navigating back from the view I wanted to simply reload the view and all the required requests (I don't see how I would prevent firing them twice - from the interceptor and from loading the state). |
This just bit me because of the difficulty in passing a URL as a param. It's doesn't seem possible to even pass an encoded URL as part of a state param, and also doesn't seem possible to set $location.query with a URL as a param. |
@xixixao, I'm still not sure I know how to do authorized client-side stuff the "right way"... but I saw this last night in angular discussion and you might be interested. This is the thread and this is the gist of something that looks like a good start on doing the authorization thing on client side . Personally, I'd like to see a strategy supported in ui-router through a "preconditions" array, but that gist is another possible way to fly. @damrbaby, you might want to frame your problem as its own question with some detail. We're deep in the weeds here and the situation you're experiencing might be unrelated -- it's difficult to tell from your comment. Examples on plunker are of course an ideal way to demonstrate issues when they are possible. HTHs! |
@stu-salsbury Sorry if I wasn't clear... what I meant was that something like this: .state('upload', url: { '/images/:upload_url' }) Is difficult to do when the $state.transitionTo('upload', { upload_url: 'http://myurl/image.png' }) Cause then you wind up with a URL that looks like this: So basically i feel like a contraint to ui-router is that it's doesn't seem possible to pass a URL as a $stateParam (url encoding it didn't help). Ideally a URL should be passed as a query parameter but ui-router does not support query params in the URL (setting I'll be happy to open a separate issue if you suggest 😄, but I felt like it's related to this cause if ui-router supported setting a query string in the URL this wouldn't be an issue. |
@damrbaby state parameters automatically have |
I think this just shows that people have different needs based on the situation and it would be nice to allow all of them (dynamic params, hidden params, query params), imo. |
@xixixao -- I think some of the issues you're finding are perfect examples of how ui-router is evolving and how it's going to be a "better way" to deal with "routing" and more importantly state management than what is built into angular today. The $state service is coming to a point where it won't care what URLs are used to refer to states and where it doesn't need them to get from state to state or know its parameters. This is huge for angular apps because they can relegate URLs to those things that are externally interesting, but not involved in how the app functions. There are some hiccoughs along the way -- places where urls were assumed when state parameters should have been the default go-to way to know what a state is composed of... these will work themselves out with the the strong ui-router team on the task... they're on it. I think what's important for wider adoption of $state is to get to a point where all of these kinks that assume the presence of a URL are worked out, and then document usage of $state in a way that reflects the lack of need to handle URLs internally, while also demonstrating how states can define URLs such that the outside world can refer to them. It'll be great! You're ahead of the curve on this... that's a great place to be! |
Thanks for all the input. What I needed was the params on the state.config. This is a sanitised version of what I am trying: .state('clients.details', { Thanks in advance. On 22 June 2013 21:07, Stu Salsbury notifications@github.com wrote:
Keith Garrod Tel: +27-83-3000-988 |
@kpgarrod just add $stateParams as a parameter to the function |
Thanks, got it. On 28 June 2013 03:04, Karsten Sperling notifications@github.com wrote:
Keith Garrod Tel: +27-83-3000-988 |
@ksperling @stu-salsbury Sorry for the delayed response. I just created a plunkr to illustrate my point: Basically, yes it does work (momentarily) to have a URL as a state param. But as soon as the state resolves itself the brower redirects to the application root (in Chrome at least) and the app will no longer be bootsrapped (unless you have a default route in place). In this example as soon as the state goes to Basically it is currently not possible to pass a URL around as a parameter as far as I can tell. |
And just wanted to follow up with a link to a slightly modified version of the previous plunker... only difference is I'm percent-encoding the URL first like @ksperling suggested, which results in the same behavior. |
@damrbaby the problem with your plunkr is that you're missing a preventDefault. If you change the 'a' to a 'span' it works as expected: http://plnkr.co/edit/7LQsDrM0I2yDJrgWgxLr?p=preview |
@ksperling Interesting. However if you were to go to that state directly it won't work. I added a "Reload window" link to show what I mean in this plunkr: http://plnkr.co/edit/fh4r97DSArNFpgIEaJzP?p=preview After reloading the window the expected behavior is that it would remain on the same state. |
Hm turns out encodeUrlComponent is only used for query parameters at the moment, not path parameters. That should probably be fixed. I seem to recall I didn't do that because core $route treats parameters as 'raw'. Medium term we'll support typed parameters, where the type defines the encoding/decoding, and have built-in types including 'raw' and 'string'... It seems like 'string' (i.e. auto encoding/decoding) would be the best default, so a break with how $routeProvider handles things by default. Or should 'raw' be the default for backwards compatibility? Especially in cases where there is a custom regex we should probably not do any additional encoding/decoding. |
Since $state requires you to pass all paramaters in the path (which is different from $route) I think it should encode / decode them by default. For states with regular expressions would it be possible to decode the path prior to testing the regex? |
@damrbaby are you aware that parameters can also be placed after the path as query parameters?
I'm not sure you can do those ones as regex though... |
Guess I need to make that clearer in the docs... |
@timkindberg what about dynamic query paramaters?
|
Query parameters are always dynamic, you wouldn't put the '=:url' part. So you'd just do this: $stateProvider.state('url', { url: '/url?url' })
$state.transitionTo('url', { url: 'http://google.com' }) Also I updated the Routing wiki page, hopefully things are more clear now. https://github.com/angular-ui/ui-router/wiki/URL-Routing |
Note that query parameters aren't "dynamic" in the sense of the "dynamic parameters" feature that's on the ui-router roadmap that would do two-way binding between $stateParams and URL without triggering a state transition. Other than the different syntax for specifying the in the URL pattern (and the difference regarding encodeUriComponent), query parameters behave pretty much identical to path parameters at the moment. |
@timkindberg didn't know about the query params, thanks! So it looks like it works fine that way: http://plnkr.co/edit/z7XKJsfUqnVEEcRQ8F3O?p=preview |
Thank you for helping me find a gaping hole in my docs! |
Just got tripped over by this as well... Perhaps there should be a big, red and bold line in the doc stating that "if a passed param does not appear inside the routeUrl template, it will be removed"? |
Follow any additional discussion of typed parameters here: #125. |
I am having difficulty passing parameters with $state.transitionTo.
My states are defined like this:
In LeadsCtrl I have a function:
The function correctly transfers state to clients.prospects and ProspectsCtrl executes, but when I do:
in ProspectsCtrl, the result is undefined.
What am I missing here please?
The text was updated successfully, but these errors were encountered: