Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular JS - UI router page reload won't set the state

This is my main app (app.js)

(function(ng, module) {
    module.config(['$stateProvider', '$urlRouterProvider', function( $stateProvider, $urlRouterProvider){

        $urlRouterProvider.otherwise("app");

        $stateProvider.state('login', {
            url: 'login',
            templateUrl: '/assets/templates/pages/login.html'
        }).state('root', {
            url: '',
            templateUrl: '/assets/templates/pages/index.html'
        });


    }]);
}) (angular, angular.module('myapp', ['ui.router', 'myapp.submodule']));

This is the submodule (submodule.js)

(function(ng, module) {
    module.config(['$stateProvider', function($stateProvider){
        $stateProvider.state('root.substate', {
            url: 'todo/{type}',
            templateUrl: '/assets/app/todo/todo.html',
            controller: function($stateParams, $scope) {
                // Do stuff.
            }
        });
    }]);

}) (angular, angular.module('myapp.submodule', ['ui.router']));

The expected behaviour would be

  • redirect to "app" url when no matching route is found
  • activate the "root" state on root url
  • activate the "root.substate" state on /todo url

This is working fine.

However, if i do refresh the page, the state is not activated and i'm sent back to "app". Why?

like image 723
brazorf Avatar asked Feb 06 '15 13:02

brazorf


1 Answers

We have two root states (no parent) states. These should be either having no url, or it should start with some unique sign - the best choice would always with (URI spec) be a /:

// domain/app/login - easy to find
.state('login', {
    url: 'login',
    ...
})
// no def === domain/app
.state('root', {
    url: '',
    ...
});

Now, let's use some url even for our 'root' state :

// domain/app/
.state('root', {
    url: '/',
    ...
});

That mans, that our child 'root.substate' will also contain the parent url part. So if we would use this

// this is a child and its url will be in fact: domain/app//todo/sometype
.state('root.substate', {
    url: '/todo/{type}',
    ...
});

See, that this way, our url will now for child contain // (double slash)

To avoid that, we can use UI-Router feature '^'

// this stat will not use the parent part
// this will work domain/app/todo/sometype
.state('root.substate', {
    url: '^/todo/{type}',
    ...
});

Check the doc:

Absolute Routes (^)

If you want to have absolute url matching, then you need to prefix your url string with a special symbol '^'.

$stateProvider
  .state('contacts', {
     url: '/contacts',
     ...
  })
  .state('contacts.list', {
     url: '^/list',
     ...
  });
like image 66
Radim Köhler Avatar answered Sep 21 '22 06:09

Radim Köhler