Mustafa
Mustafa

Reputation: 6144

Navigation using Angularjs $state.go

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.

Upvotes: 2

Views: 2577

Answers (1)

Pankaj Parkar
Pankaj Parkar

Reputation: 136134

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

Upvotes: 2

Related Questions