3

I have an Angular application using ui-router and I am having issues whenever I refresh the page. I am using nested views, named views to build the application. Whenever I refresh the page, ui-router doesn't reload the current state and just leaves the page blank.

On page load $state.current is equal to

Object {name: "", url: "^", views: null, abstract: true}

I am reading my navigation from a .json file via $http and looping through the states. So this is what I can show:

stateProvider.state(navElement.stateName, {
    url: navElement.regexUrl ? navElement.regexUrl : url,
    searchPage: navElement.searchPage,   //something custom i added
    parent: navElement.parent ? navElement.parent : "",
    redirectTo: navElement.redirectTo,
    views: {
        'subNav@index': {
            templateUrl: defaults.secondaryNavigation,
            controller: 'secondaryNavigationController as ctrl' //static
        },
        'pageContent@index': {
            template: navElement.templateUrl == null 
                                              ? '<div class="emptyContent"></div>' 
                                              : undefined,
            templateUrl: navElement.templateUrl == null 
                                              ? undefined 
                                              : navElement.templateUrl,
            controller: navElement.controller == null 
                                              ? undefined 
                                              : navElement.controller + ' as ctrl'
        }
    }
});

This code gets executed for each item in the nested json object. If there is anything else that would be helpful, let me know.

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
gwin003
  • 7,432
  • 5
  • 38
  • 59

2 Answers2

5

There is a question: AngularJS - UI-router - How to configure dynamic views with one answer, which shows how to do that.

What is happening? On refresh, the url is evaluated sooner, then states are registered. We have to postpone that. And solution is driven by UI-Router native feature deferIntercept(defer)

$urlRouterProvider.deferIntercept(defer)

As stated in the doc:

Disables (or enables) deferring location change interception.

If you wish to customize the behavior of syncing the URL (for example, if you wish to defer a transition but maintain the current URL), call this method at configuration time. Then, at run time, call $urlRouter.listen() after you have configured your own $locationChangeSuccess event handler.

In a nutshell, we will stop URL handling in config phase:

app.config(function ($urlRouterProvider) {
 
  // Prevent $urlRouter from automatically intercepting URL changes;
  // this allows you to configure custom behavior in between
  // location changes and route synchronization:
  $urlRouterProvider.deferIntercept();
 
})

And we will re-enable that in .run() phase, once we configured all dynamic states from JSON:

.run(function ($rootScope, $urlRouter, UserService) {
 
  ...

    // Once the user has logged in, sync the current URL
    // to the router:
     $urlRouter.sync();
 
    // Configures $urlRouter's listener *after* your custom listener
    $urlRouter.listen();
});

There is a plunker from the linked Q & A

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Just a NOTE. I expected that statement in question ***"..I am reading my navigation in from a json file..."*** means you are doing it from loaded `.json`, loaded via `$http`. If not, my answer would not help... – Radim Köhler Apr 29 '15 at 12:41
  • I am loading a json file through $http calling to a WebApi service, so your answer still applies. Though I added `deferIntercept()` to my config and `sync()` and `listen()` to my run method, I am still running into the same issue. – gwin003 Apr 29 '15 at 13:01
  • I am using the same in real life. 1:1. I would suggest, investigate my plunker and that should help (plus details in the linked Q & A). Or adjust my plunker, and show me what is not working... Because with snippet in your question it is almost the max I can show, I can suggest... Does it make sense? – Radim Köhler Apr 29 '15 at 13:02
  • The only difference looks to be that your urls contain `^` and mine do not. Could that be the culprit? – gwin003 Apr 29 '15 at 13:52
  • This is just a "reseter" of the url. Without it - children inherit first part from parent. With this sign, children url is starting from the beginning. So, I would doubt this is an issue... – Radim Köhler Apr 29 '15 at 13:53
  • Debugging the ui-router source now, I'll report back. It seems as if the `check()` function inside the `update()` function is not handling the urls whenever the rules are checked. Could be that my urls are not setup properly on my states. My urls are setup like this: http://pastebin.com/ZHepheCX – gwin003 Apr 29 '15 at 14:38
  • 1
    I was able to get my solution pretty much resolved now. It was a 2 part issue, adding the `deferIntercept()`, `sync()` and `listen()` solved one part of the issue. I was also seeing issues if my URL had a trailing slash, so adding `$urlMatcherFactoryProvider.strictMode(false)` resolved that issue. Thanks for saving me again @RadimKohler! – gwin003 Apr 30 '15 at 11:25
  • @RadimKöhler this solves my issue when refreshing child states. but if i try to access base index '/' only. I get an infinite refresh automatically. – LogronJ Sep 05 '18 at 09:27
  • i have an $urlRouterProvider.otherwise('/'); it should go to a specific state. – LogronJ Sep 05 '18 at 09:30
1

I don't know how are all your routes.. but if you refresh a page of a child state, you need to pass all parameters of the parents states to be resolved correctly.

manzapanza
  • 6,087
  • 4
  • 39
  • 48