2

I'm trying to create a simple navigation area in my single-page application. It is made up of a bunch of links in a list. Each one calls a method in a NavigationController. The method, in turn, calls $state.go passing it a state string. I have configured an "otherwise" path in case my state is not resolved. The problem is that I'm always getting the "otherwise" template instead of the one specified in the state. I see that my controller method is being called, so the state transition is working to some extend. But I can't see why I end up with the default template.

Here is my code (a link to a fiddle is below):

var app = angular
  .module("AppName", ['ui.router']);

angular
  .module("AppName")
  .config(['$locationProvider',
    function ($locationProvider) {
      $locationProvider.hashPrefix('!');
    }
  ]);

angular.module("core", []);
angular
  .module("AppName")
  .requires
  .push("core");

angular
  .module("AppName")
  .controller('NavBarController', ['$scope', '$state',
    function ($scope, $state) {
      $scope.username = null;
      $scope.showNavBar = true;
      $scope.navCollapsed = true;

      $scope.goToProfile = function () {
        console.log("goToProfile.");
        $state.go('profile')
      }

      $scope.goToHistory = function () {
        console.log("goToHistory");
        $state.go('history')
      }
    }]);

angular
  .module('core')
  .config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise(function ($injector, $location) {
      console.log("Could not find: " + $location.$$path);
      $location.path('/home');
    });

    $stateProvider
      .state('home', {
        url: '/home',
        template: '<div> {{welcome}} </div>',
        controller: 'HomeController'
      });
    $stateProvider
      .state('profile', {
        url: '/profile',
        template: '<div>This is {{username}}\'s profile! </div>',
        controller: 'ProfileController'
      });
    $stateProvider
      .state('history', {
        url: '/history',
        template: '<div>{{history}}</div>',
        controller: 'HistoryController'
      });
  }])

angular
  .module('core')
  .controller('HomeController', ['$scope',
    function ($scope) {
      $scope.welcome = "Welcome Home!";
    }]);

angular
  .module('core')
  .controller('ProfileController', ['$scope',
    function ($scope) {
        console.log("Running ProfileController.")
      $scope.username = "Bunny the rabbit";
    }]);

angular
  .module('core')
  .controller('HistoryController', ['$scope',
    function ($scope) {
        console.log("Running HistoryController.")
      $scope.history = ["item1", "item2", "item3"];
    }]);


angular
  .element(document)
  .ready(function () {
    if (window.location.hash === '#_=_') {
      window.location.hash = '#!';
    }
    angular.bootstrap(document, ["AppName"]);
  });

And my html:

 <body>
  <div ng-controller="NavBarController">
        <ul>
          <li><a href="#" ng-click="goToProfile()">Profile</a></li>
          <li><a href="#" ng-click="goToHistory()">History</a></li>
        </ul>
  </div>
      <div class="app">
        <div class='app-body'>
          <div class='app-content'>
            <ui-view class="ng-scope">
              <div>
              Some place holder html
              </div>
            </ui-view>
          </div>
        </div>
      </div>
  </body>

I have created a fiddle here.

I have some familiarity with angularjs but this issue has stumped me. As far as I understand the $state.go call should trigger a state transition which mean applying the new state's template. For some reason, this seemingly simple scenario is not working here. I tried other answers in SO but nothing helped. I suspect that I'm overlooking something that's interfering with this behavior.

2
  • 1
    Since you're using UI Router, is there any reason you're using ng-click over ui-sref? Commented May 10, 2016 at 12:12
  • @JAAulde no particular reason except that, until yesterday, I wasn't aware of ui-sref. I guess it is better to use it here. Commented May 10, 2016 at 23:59

1 Answer 1

2

Do remove # from href of your anchor tags. when you had href with # they gets redirected to $urlRouterProvider.otherwise where no state URL gets match.

Markup

<ul>
   <li><a href="" ng-click="goToProfile()">Profile</a></li>
   <li><a href="" ng-click="goToHistory()">History</a></li>
</ul>

Forked Fiddle

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you @Pankaj, this is what has taken the last 3 hours of my day! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.