christopherthielen / ui-router-extras

THIS PROJECT IS NO LONGER MAINTAINED -- Extras for UI-Router for AngularJS. Sticky States (a.k.a. parallel states), Deep State Redirect (for tab-like navigation), Future States (async state definition)
http://christopherthielen.github.io/ui-router-extras/
MIT License
917 stars 211 forks source link

$state.reload() throws exception #340

Closed jorisvddonk closed 7 years ago

jorisvddonk commented 7 years ago

Calling $state.reload() throws an exception when using ui-router-extras 0.1.2, angularJS 1.5.8 and ui-router 0.2.18:

TypeError: undefined is not a function
at Object.$state.transitionTo (ct-ui-router-extras/src/sticky.js:310)
at Object.reload (angular-ui-router.js:3035:21)

The problem is that reloadStateTree.$$state is undefined here.

jorisvddonk commented 7 years ago

I've taken a quick look at the code in question and I think I may have been able to fix this by replacing lines 310 and 311 in sticky.js with the following:

var params = (reload === true ? savedToStatePath[0].params : reloadStateTree.$$state().params);
var ownParams = (reload === true ? savedToStatePath[0].ownParams : reloadStateTree.$$state().ownParams);

After this patch, the exception no longer happens and my state appears to reload correctly.

christopherthielen commented 7 years ago

That's strange. Is this issue minimally reproducible (in a plunker or whatever)?

 var reloadStateTree = reload && (reload === true ? savedToStatePath[0].self : $state.get(reload, rel));

It looks like reloadStateTree should either be false or a state. What is its actual value? If it's a state, ui-router-extras core should have added the $$state() function to the state when it was registered.

https://github.com/christopherthielen/ui-router-extras/blob/master/src/core.js#L4-L18

I think your proposed fix might be masking a symptom of some other problem.

jorisvddonk commented 7 years ago

You're absolutely right. My proposed fix did indeed mask the symptom of some other problem, which I was able to uncover after further digging through both my own codebase and ui-router-extra's codebase. My own code turned out to be at fault here.

For those interested or those affected by the same issue, here's what was wrong; I have a rather complex state tree, defined across multiple AngularJS modules for the best possible code reuse. A 'root' AngularJS module defined a state that was used as a parent state for most other states. These other states were defined in several 'app' AngularJS modules. The app modules depended on ui-router-extras (which added the $$state() function to each defined state), whereas the root module didn't, thus causing the exception to trigger whenever $state.reload() was called. Ensuring that the root module also depended on ui-router-extras fixed the issue.

christopherthielen commented 7 years ago

Good work tracking that down!

hahaniu666 commented 6 years ago

Reproduced this problem. The reason is forgot to add ui-router-extras dependency to my angular module:

export default angular.module(`${conf.app}.states.main`, [
    uiRouter,
    'ct.ui.router.extras.core',                   // add these lines fix it
    'ct.ui.router.extras.dsr',
    'ct.ui.router.extras.future',
    'ct.ui.router.extras.previous',
    'ct.ui.router.extras.statevis',
    'ct.ui.router.extras.sticky',
    'ct.ui.router.extras.transition'
]).config(confState).run(function () {});