-
Notifications
You must be signed in to change notification settings - Fork 3k
Resolve promise each time before controller is executed #2604
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
Comments
As you probably know, neither resolves nor controllers are reloaded for "retained" states. When navigating from child to child, or child to parent, the parent state is retained; it is neither entered nor exited. If you're writing a third party extension, I do not recommend forcing other people's apps to The 1.0 transition rewrite addresses your use case. Transition hooks can pause the transition while waiting for some promise. The hooks can be added to transitions in a flexible, declarative way. However, the "retained" controllers will still not be reloaded. |
Thank you @christopherthielen for elaborated answer! It's a shame that UI Router doesn't provide any hooks to execute custom code before any transition while pausing it at the same time in current incarnation. That makes my life extremely difficult, because it's a great place to implement authentication/authorization, state customization and such. Are there any estimates on release date for Also, is there an API docs for Thank you very much for your hard work! It's highly appreciated! |
Read over our release notes and the list of breaking changes #2219 The docs are currently at http://angular-ui.github.io/ui-router/feature-1.0/ but are very much a work in progress. See http://angular-ui.github.io/ui-router/feature-1.0/classes/transition.hookregistry.html for the transition hook documentation. I think alpha0 is pretty solid and will likely work fine for your app in production. There will be some bugs in there, which may or may not affect your app. Some of the new APIs will be tweaked before final release. |
Thanks! That's pretty cool piece of software you've got there. I think it will solve a lot of concerns. Waiting forward to see it in production! Godspeed! |
closing due to inactivity |
I am wondering why few people actually take part of the discussion, because the OP's usecase seems pretty common. I deal with the very same problem and my only workaround for now was to define a stateDecorator that force reloads the state so that I can be sure even if I visit a child state my resolved data is up to date. That's not a good solution as you mentioned because I dont want to re-initialize every parent controller when I visit a child state. What is the best solution for ensuring that only the resolves are up to date down the state tree? |
Tell me exactly what you want to do. It sounds like you want some object defined at a parent state, injected into children states, then have that object dynamically update whenever the user activates any substate. Is that correct? This is the typical use case that resolve is used for:
There's no baked-in mechanism for modifying a resolved value without reloading the state. Reloading the state ensures that 1) the resolve is fetched and 2) the resolve can be injected into a child (it's a different object reference, after all). If you want to dynamically update an object reference, you'll have to manage that state yourself. This sounds like it might be a good use case for Observables. |
Hello @christopherthielen, your assumption is on point. We use resolves to fetch data from our backend. This requests don't have to be necessarily bound to a route parameter. For example we have a user object that we need on almost all our states, so we defined a resolve on the root state so it is avaiable on all our child states. Of course the user can update his profile on various pages and the data gets saved in the backend. Now we have exactly the problem as you described: We have to reload our root state to get this user object updated (we have datastores, so it's not another request to the backend in case you wonder). But anyway we have to re-resolve it and reloading the whole state tree is not an option. We have events available for all our datastores. So if an object is updated in the datastore an event is triggered and for example a controller can listen on this event and update the data. The problem here is that we have a lot of data and with this approach we have to define the listeners in all our controllers which causes a lot of boilerplate. I know that problem might not be related to ui-router as it is more of a general dataflow architecture question. What we like about resolves:
What we don't like:
|
@chillyistkult Do you want to inject the resolved value into the newly activated CHILD or some PARENT? If you only care to inject it into a child, this is achievable using 1.0. However, you can't change the resolve value injected into a parent, for (possibly obvious) reasons. In 1.0 you can add a resolve to any transition on the fly. The resolved data is available to be injected in any newly entered states and their components. I think you might really benefit from using Observables though. You can resolve to an Observable (once, in the root state), and that single Observable can stream values, as they change. |
For me it would have been important to inject AND update the resolved value down the state tree (parent and it's childs), to ensure that all related controllers are getting up to date data. In 1.0 this would be solvable but not in a way that it's feasible on big projects. So we shifted away from the idea to "abuse" the state resolve functionality as a system to update and deliver data across the app (however I somehow liked the idea it seemed simple and intuitive). We recently implemented event driven datastores (observable) as you suggested. |
Understood. Resolving the data directly in the parent state definitely isn't the right solution for that. I think your event driven datastores (possibly even exposed to states as a resolve) seems like an appropriate solution here. |
Hello!
Thank you for this great module and your awesome work!
However, I'm looking for a way to run my asynchronous function before the controller is executed for some state. I want this to happen every time when client is transitioned to the state.
I've tried to use
resolve
object in a state configuration, however, the resolves will not be re-evaluated when navigating from child to parent state and I don't want to callreload
manually or provide it as an argument somewhere.Also, I know that I can prevent navigation in the
$stateChangeStart
event and then manually continue it, but it will reject the original promise, which I don't want.Are there any real alternatives? I've spent almost two days trying to figure out this pretty simple usage scenario.
Actually, I'm implementing an extension module for UI Router that will support conditional stylesheets. Developer will be able to define the list of named resources as a part of state configuration and they whould be loaded when the state is activated, before the view is rendered and controller is executed. I will gladly accept any suggestions!
Or probably there is a function that determines whether the state needs to be reloaded. Is there a way to decorate/overload it? That way I will be able to compare required resources between states and make a decision.
Right now I'm using $state service decorator as a temporary workaround:
But I'm not really sure if it's safe to use such approach.
Thank you!
The text was updated successfully, but these errors were encountered: