Search code examples
angularjsangularjs-scopeangular-ui-routerangularjs-controllerangular-ng-if

Hiding navbar based on current path with AngularJS ($scope vs. controller as syntax)


I'm working with the Inspinia Admin Theme (AngularJS Version) and have the following Problem.

I'm trying to show or hide the navbar based on the current path. The Problem with my first approach (controller as syntax) is that the navbar is hidden regardless of the current path:

'use strict';

angular.module('inspinia')
  .controller('MainController', function ($location) {

  // use vm instad of $scope
  var vm = this;

  // show or hide navbar based on current path
  if ($location.path().indexOf('resetpass') > -1) {
    vm.hideNavbar = false; // false: hide navbar, true: navbar visible
  }else {
    vm.hideNavbar = true;
  }
});

If I do it with $scope (see below), the visibility of the navbar responds to the current path, but only after refreshing the current page. So I only get the new path and desired functionality after a refresh (cmd + r).

angular.module('inspinia')
  .controller('MainController', function ($location, $scope) { 

  // show or hide navbar based on current path
  if ($location.path().indexOf('resetpass') > -1) {
    $scope.hideNavbar = false; // false: hide navbar, true: navbar visible
  }else {
    $scope.hideNavbar = true;
  }
});

In addition I get the following errors in the console:

 15:7  error  You should not set properties on $scope in controllers. Use controllerAs syntax and add data to "this"  angular/controller-as
 17:7  error  You should not set properties on $scope in controllers. Use controllerAs syntax and add data to "this"  angular/controller-as

 ✖ 2 problems (2 errors, 0 warnings)

My HTML looks like this (content.html):

<div id="page-wrapper" class="white-bg {{$state.current.name}}">

    <!-- Page wrapper -->
    <div ng-include="'app/components/common/topnavbar.html'" ng-if="hideNavbar"></div>

    <!-- Main view  -->
    <div ui-view></div>


</div>

(index.html):

  <body ng-controller="MainController as main">

    <div ui-view></div>

  </body>

What am I doing wrong?


Solution

  • I am late to post the answer, but hope it will help in further development and understanding.

    angular.module('inspinia')
      .controller('MainController', function ($location, $scope) {
    
      // use vm instad of $scope
      var vm = this;
    
      // show or hide navbar based on current path
      $scope.$watch(function() {
        return $location.path();
      }, function(newPath, oldPath) {
        if (newPath.indexOf('resetpass') > -1) {
          vm.hideNavbar = false; // false: hide navbar, true: navbar visible
        }else {
          vm.hideNavbar = true;
        }
      });
    });
    

    Look at above code of controller. In that I have used $scope.$watch to constantly look at the location path. Whenever the path will be changed, watcher will get the change and then your code will work fine. So you will not need to reload page.

    Your content.html must look like:

    <div id="page-wrapper" class="white-bg {{$state.current.name}}">
    
        <!-- Page wrapper -->
        <div ng-include="'app/components/common/topnavbar.html'" ng-if="main.hideNavbar"></div>
    
        <!-- Main view  -->
        <div ui-view></div>    
    </div>
    

    When you use controller as syntax, there must not be $scope to assign and access $scope variables in view. Variable used in controller as will be the object that will hold all variables assigned in controller via this object.

    Hope the answer will be useful in future.

    Thanks & Regards.