s_p
s_p

Reputation: 4693

AngularJS component controller syntax

I have a component() which injects a nav. When I try to include the controller inside this component like so, I get an error.

inside nav.html

<nav class="navbar navbar-inverse navbar-fixed-top">
  <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">Demo</a>
    </div>
    <div id="navbar" class="collapse navbar-collapse" ng-controller="MainMenuController">
      <ul class="nav navbar-nav">
        <li ng-class="{ active: isActive('') }"><a href="./">home</a></li>
        <li ng-class="{ active: isActive('/skus') }"><a href="sku.html">sku</a></li>
        <li ng-class="{ active: isActive('/phones') }"><a href="phone.html">phone</a></li>
      </ul>
    </div><!--/.nav-collapse -->
  </div>
</nav>


inside component.js

angular.
module('mainMenu').
component('mainMenu', {
  templateUrl: 'app/core/nav/nav.html',
  controller: 'MainMenuController', ['$scope', '$location', 
    function NavController($scope, $location) {
        $scope.isActive = function (viewLocation) { 
          var p1 = $location.path();
          var p2 = '/' + p1.split("/")[1]; // split string from '/';
          if(p2=='/undefined') p2 = '';
          return viewLocation === p2;
        }
    }
  ]
});

But if I write a separate controller like this everything works fine. What am I doing wrong with component() and should I not be including the controller in component() for best practice?

angular.
module('mainMenu').
component('mainMenu', {
  templateUrl: 'app/core/nav/nav.html',
});


angular.
module('mainMenu').
controller('MainMenuController', ['$scope', '$location', 
      function NavController($scope, $location) {
        //this.navs = Nav;
        $scope.isActive = function (viewLocation) {
          var p1 = $location.path();
          var p2 = '/' + p1.split("/")[1]; // split string from '/';
          if(p2=='/undefined') p2 = '';
          return viewLocation === p2;
        };
      }
]);


I changed my component to this

angular.
module('mainMenu').
component('mainMenu', {
  templateUrl: 'app/core/nav/nav.html',
  controller: ['$scope', '$location', 
    function MainMenuController($scope, $location) {
      //this.navs = Nav;
      $scope.isActive = function (viewLocation) {
        var p1 = $location.path();
        var p2 = '/' + p1.split("/")[1]; // split string from '/';
        if(p2=='/undefined') p2 = '';
        return viewLocation === p2;
      };
    }
  ]
});

getting error Error: [ng:areq] http://errors.angularjs.org/1.5.8/ng/areq?p0=MainMenuController&p1=not%20a%20function%2C%20got%20undefined N



Fix: By cleaning up the module and component titles and making them unique, removing ng-controller from the template; Neal Hamilton's answer below fixed my original question.

Upvotes: 1

Views: 5876

Answers (1)

nham
nham

Reputation: 161

this is my preference when adding controllers...

MainMenuController.$inject = ['$scope', '$location'];
function MainMenuController($scope, $location) {}

angular.module('menu').component('mainMenu', {
    controller: MainMenuController,
    controllerAs: 'MainMenuController',
    templateUrl: 'app/core/nav/nav.html'
});

the style you're trying to do with dependencies inline...

angular.module('menu').component('mainMenu', {
    controller: ['$scope', '$location', function($scope, $location) {}],
    controllerAs: 'MainMenuController',
    templateUrl: 'app/core/nav/nav.html'
});

Difference being that you had the ControllerAs String with the controller declaration. You should be using the controllerAs: "NameForController" property to name the controller.

Good Luck!

Upvotes: 5

Related Questions