t q t q - 2 months ago 24
AngularJS Question

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.

Answer

this is my preference when adding controllers...

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

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

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

angular.module('mainMenu').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!