Skip to content
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

0.2.11 regression: "resolve" dependency collision with parent state #1485

Closed
metamatt opened this issue Oct 27, 2014 · 2 comments
Closed

0.2.11 regression: "resolve" dependency collision with parent state #1485

metamatt opened this issue Oct 27, 2014 · 2 comments

Comments

@metamatt
Copy link

I'm working on an app using ui-router that makes heavy use of a helper object, call it perStateHelper, that's built on the fly for each state and injected into the controller for that state's view, via the resolve map on the state.

All the states in my app have this perStateHelper, and all the controllers use it.

I had this working fine using ui-router 0.2.10; over the weekend I attempted to upgrade to ui-router 0.2.11 and found that this no longer works. This may be a regression in ui-router 0.2.11, or it may be that I was misusing the functionality somehow and it just happened to work before, but there's definitely a behavior change from 0.2.10 to 0.2.11 here. From looking at the release notes and the diff to angular-ui-router.js from 0.2.10 to 0.2.11, I couldn't figure out what the relevant change was, though.

I spent a fair amount of time annotating and stepping through the ui-router code and I can see the direct reason my code doesn't work in 0.2.11, but I don't know why this actually is. Hopefully this will be immediately obvious to someone involved with the project. From $state.transitionTo(), we call into resolveState() for each new state to enter, to resolve dependencies. in resolveState(), there are two calls to $resolve.resolve(), the first to resolve the state.resolve map, the second to resolve the view.resolve map (well, injectables, which is calculated as view.resolve if view.resolve is present and differs from state.resolve, else the empty object). The first one of these resolve calls populates locals.globals for the state, and the second one populates locals[viewName] for all named views.

I'm not using the named-views feature; that's to say each state has only one view, which becomes the default @stateName view.

So after resolveState has done its thing and the promises actually resolve, the locals object attached to my state has properties globals and @stateName. The copy of perStateHelper in locals.globals is correct. The copy of perStateHelper in locals['@stateName'] is incorrect; it belongs to a parent state. (But in 0.2.10, this was not a problem.)

What I don't understand is

  • why locals.globals and locals['@stateName'] exist separately and can be different
  • why (in ui-router 0.2.11, but not in 0.2.10) the locals['@stateName'] is inherited from a parent state instead of being the one we actually built for this state

Here's a plunker which demonstrates the problem and is hopefully straightforward enough to follow (I just hacked it on top of one of the standard ui-router demos, the "Go to Quick Start Plunker for Nested States & Views" from the ui-router README.md).

The idea is that each state (the two toplevel states, route1 and route2, and their two child states, route1.list and route2.list) provides the perStateHelper via the resolve map on the state. Here, the perStateHelper is just a silly function that returns a unique instance number each time it's called, so you can see which instance you're dealing with, and the state's controller injects this dependency and copies it into the scope and the view template displays it, so you can see visually which instance of perStateHelper got injected into the controller.

How it should work: If you run the bug demo plunker with ui-router 0.2.10, if you enter either the route1 or route2 state you'll see a number next to "data", and if you click "show list" to enter the child state, you'll see a different number, proving that the child state got a different instance of perStateHelper.

The bug: if you run the bug demo plunker with ui-router 0.2.11, if you enter either the route1 or route2 state you'll see a number next to "data", and if you click "show list" to enter the child state, you'll see the same number again, proving that the child state got the parent's instance of perStateHelper. But perStateHelper was actually instantiated for this state, so if you switch over to the other toplevel state, you'll see the number increment by 2.

@christopherthielen
Copy link
Contributor

Hi, I appreciate the detailed bug report! I think you're seeing the same issue as #1353 and #1317. Fixed in #1360.

I updated your plunk to the 0.2.12-pre1 release and I believe it behaves as you expect it should. Please confirm and close this issue.

@metamatt
Copy link
Author

Yep, same issue, and the fix works for me. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants