angular-ui / ui-router

The de-facto solution to flexible routing with nested views in AngularJS
http://ui-router.github.io/
MIT License
13.56k stars 3.01k forks source link

ui-router changes the url but view does not change #3652

Closed JanuszCh closed 3 years ago

JanuszCh commented 6 years ago

This issue tracker is for Bug Reports and Feature Requests only.

My version of UI-Router is: 1.0.15

General Query

In my app, I have a bug. From time to time (especially on slow internet connection) when I try to go from app.login.account to app.dashboard.expert.activities the state is changing but the view is not.

Every request when login is OK 200

I use trace from ui-router and I got:

trace.js:154 Transition #14-0:   Hook -> onFinish context: app.dashboard.expert.activities, function loadEnteringViews(transition)
trace.js:224 VIEWCONFIG: Loaded [View#45 from 'app.dashboard.expert.activities' state]: target ui-view: '$default@app.dashboard.expert'
trace.js:160 Transition #14-0:   <- Hook returned: "undefined"
trace.js:184 Transition #14-0: <- Success  "Transition#14( 'app.login.account'{} -> 'app.dashboard.expert.activities'{} )", final state: app.dashboard.expert.activities
trace.js:154 Transition #14-0:   Hook -> onSuccess context: app.dashboard.expert.activities, function transitionSuccessful()
trace.js:154 Transition #14-0:   Hook -> onSuccess context: app.dashboard.expert.activities, function updateUrl(transition)
trace.js:154 Transition #14-0:   Hook -> onSuccess context: app.dashboard.expert.activities, function activateViews(transition)
trace.js:224 VIEWCONFIG: <- Removing [View#42 from 'app.login.account' state]: target ui-view: '$default@app.login
trace.js:224 VIEWCONFIG: -> Registering [View#45 from 'app.dashboard.expert.activities' state]: target ui-view: '$default@app.dashboard.expert''

https://i.stack.imgur.com/lByUR.png

There is not ui-view: Updating in the console.

I think the problem is (as You can see on above screen from console) that the state is changing not from root state app but from app.dashboard Correct login: https://i.stack.imgur.com/eLYHQ.png

Link to Plunker or stackblitz that reproduces the issue:

This Plunker, of course, is just a scratch that how routes look.

http://plnkr.co/edit/gqp8QjCZeCtB8QPgemeu?p=preview

Thank you in advance for your time and help.

christopherthielen commented 6 years ago

Are you using sticky states by chance? This screenshot shows that the previous views from app.login and app.login.account are still active when app.dashboard.* has been activated.

When ui-router switches from app.login.account to app.dashboard.expert.activities, it should have exited both app.login.account and app.login. After the transition is complete, the activateViews() function is called. activateViews should deactivate the exited states' viewconfigs and activated any entered states' viewconfigs.

https://github.com/ui-router/core/blob/a2dbd9e4fd90fcc483f5df223521c4d45605a71b/src/hooks/views.ts#L29-L50

Can you try stepping through this section of code when the error occurs? In particular, exitingViews should include the view configs from app.login.account and app.login.

Also can you include all the trace output?

Are there no other error messages in the console/defaultErrorHandler?

DoubleDot commented 5 years ago

I'm having the exact same problem. Users are complaining about an "unresponsive browser" but the URL actually changes, the view just isn't rendered. Because it seems to be happening randomly, i tried to reproduce the issue on my system.

I can make ui-router fail to load views if i quickly click between the srefs in my navigation bar. Attached is a full trace output when this issue is occuring.

chrome_2018-07-25_11-29-50

chrome_2018-07-25_11-29-28

chrome_2018-07-25_11-29-07

In the last screenshot, i can see there are some leftover views that probably didn't get rendered in time.

In short: if i quickly switch between views that are "heavy", at a certain point the view stops updating but the url keeps changing. Other users have this randomly, presumeably when a view didn't load completely and they click another link.

Hope this helps.

pCyril commented 5 years ago

Hello @DoubleDot did you find a solution about your issue ? We have the same problem with our projet. Thanks for your help.

DoubleDot commented 5 years ago

Hi @pCyril ,

we are currently using a simple system to keep track of an active transition.

Set a default value for false app.value('transtionChecker', { inProgress: false })

and in your onBefore

    $transitions.onBefore({
        priority: 1,
        to: function (state) {
            return globals.anonymousStates.indexOf(state.name) == -1;
        }
    }, function (transition) {

        if (transition.ignored()) {
            return transition;
        }

        if (transtionChecker.inProgress == false) {

            transition.promise.finally(function () {
                transtionChecker.inProgress = false;
            }); // mark the transition as not in progress once it finally resolves
            transtionChecker.inProgress = true;
                return transition;
            }
        } else {
            return false;
        }
    });

This way, when a transitition is in progress, the new one will not fire, and will not cause ui-router to forget what it should be doing. Let me know if you need more info.

pCyril commented 5 years ago

Thanks for you answer, we finally found where was our problem, we were using onbefore to refresh authentication token, we changed that and we don't have this issue anymore.

septemptus commented 5 years ago

I am having the same issue, I did some basic investigation, and it seems to happen when I fire two transitions in rapid succession. Both of these transitions use onBefore hooks with promises to fetch recent data.

From what I saw the issue is with clearing the _viewConfigs array in the ViewService. Basically when the first transition is done it properly clears up the 'exiting' view configs from the _viewConfigs, but when the 2nd transition is done it has stale information about the exiting configs (it was created when the initial view was still active), and it attempts to remove them, instead of the configs for the currently active view (from the successful first transition).

This causes the _viewConfigs array to clutter, and that clutter prevents the ui-view from being set up properly, as the config that is selected for it is the first config in a sorted array, which happens to be one of the stale configs.

If you need more details let me know.

timruhle commented 4 years ago

This is the same issue as #3772. I hacked a fix by putting the following into the onStart event

let toList = transition.treeChanges().to.map((t) => {
  return t.state.name;
});
transition.router.viewService._viewConfigs = transition.router.viewService._viewConfigs.filter((vc) => {
  return toList.includes(vc.viewDecl.$context.name);
});

This cleans up the _viewConfigs and removes anything not related to the current transition. This same code could be put into the activateViews function in ui-router/core to fix the issue. This solution may not be the most elegant and may not be completely fool proof, but it seems to have fixed the issue for me.

@christopherthielen It would be great to get this fixed in ui-router properly.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

This does not mean that the issue is invalid. Valid issues may be reopened.

Thank you for your contributions.

christopherthielen commented 3 years ago

not stale

benstaker commented 3 years ago

This is the same issue as #3772. I hacked a fix by putting the following into the onStart event

let toList = transition.treeChanges().to.map((t) => {
  return t.state.name;
});
transition.router.viewService._viewConfigs = transition.router.viewService._viewConfigs.filter((vc) => {
  return toList.includes(vc.viewDecl.$context.name);
});

This cleans up the _viewConfigs and removes anything not related to the current transition. This same code could be put into the activateViews function in ui-router/core to fix the issue. This solution may not be the most elegant and may not be completely fool proof, but it seems to have fixed the issue for me.

@christopherthielen It would be great to get this fixed in ui-router properly.

Thanks. This solved the issue I had with UI Router not reloading the view for me. The URL was changing, but the ui-view's were not updating.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

This does not mean that the issue is invalid. Valid issues may be reopened.

Thank you for your contributions.

RFMV34 commented 4 months ago

still presented...