This seems to be yet another variation on a very common theme with Angular. I have a controller that isn't being picked up and I can't pinpoint what's missing.
Here are the key areas:
My Layout.cshtml page has the following:
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="http://cdn.date-fns.org/v1.3.0/date_fns.min.js"></script>
<script src="~/js/utility/utility.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="https://code.angularjs.org/1.5.8/angular-route.min.js"></script>
<script src="~/js/app.js"></script>
<script src="~/js/utility/config.js"></script>
<!-- models -->
<script src="~/js/models/game.js"></script>
<!-- services -->
<script src="~/js/services/game.js"></script>
<!-- controllers -->
<script src="~/js/controllers/home-controller.js"></script>
App.ts looks like this:
/// <reference path="utility/utility.ts" />
var app;
(function () {
'use strict';
app = angular.module(Utility.Resources.appName, ['ngRoute'])
})();
My config.ts is set up like this (a few deliberate redundancies in the routes to begin with):
(function () {
'use strict';
app.config(function ($routeProvider, $locationProvider) {
console.info('routes');
$routeProvider.when(Utility.Urls.game, {
templateUrl: Utility.Templates.game
}).when(Utility.Urls.home, {
templateUrl: Utility.Templates.home
}).when(Utility.Urls.team, {
templateUrl: Utility.Templates.team
}).otherwise({
redirectTo: Utility.Urls.home
//templateUrl: Utility.Templates.home
});
$locationProvider.html5Mode(true);
});
app.run(function ($rootScope, $location) {
console.info('running');
$rootScope.$on('$routeChangeStart', function (event, nextRoute, currentRoute) {
console.info("Started");
});
});
})();
And the controller in question looks like this:
var Controllers;
(function (Controllers) {
'use strict';
var Home = (function () {
function Home($scope, gameService) {
$scope.vm = this;
console.info("In Home Controller");
$scope.games = [];
$scope.categories = [];
$scope.selectedGame = {};
gameService = gameService;
$scope.get = function () {
console.info("Getting");
};
}
Home.$inject = [
Utility.Angular.$scope, Utility.Services.gameService
];
return Home;
}());
Controllers.Home = Home;
})(Controllers || (Controllers = {}));
So far I can't see anything that's obviously missing but when opening the home template...
<div class="row" ng-controller="Controllers.Home">
<div class="col-md-3">
<h3>Games</h3>
<ul class="list-group">
<li class="list-group-item list-group-item-info" ng-repeat="game in games" id="{{game.Id}}" ng-click="get(game.Id)">
<div>
<p><span class="meta">{{game.Date}}</span> <span class="pull-right"><i class="glyphicon glyphicon-calendar"></i> {{game.Season}}</span></p>
<p>{{game.Team.Name}} vs {{game.Opposition}}</p>
</div>
</li>
</ul>
</div>
... the debugger returns the following error: Argument 'Controllers.Home' is not aNaNunction, got undefined.
So I'm sure I've overlooked something. Perhaps a dependency in my controller or maybe one of the models? Except I'm not seeing any other errors in the debugger that would indicate a problem.
Any ideas?
UPDATE:
georgeawg is basically right. The missing part is in my config:
app.config(function ($routeProvider, $locationProvider) {
console.info('routes');
$routeProvider.when(Utility.Urls.game, {
templateUrl: Utility.Templates.game
}).when(Utility.Urls.home, {
templateUrl: Utility.Templates.home,
controller: Controllers.Home // <- here
...
Be sure to declare the controller function to the module as a controller type.
app.controller("Controllers.Home", Controllers.Home);
From the Docs:
Error: ng:areq
Bad Argument
Argument 'Controllers.Home' is not a function, got undefined
Description
AngularJS often asserts that certain values will be present and truthy using a helper function. If the assertion fails, this error is thrown. To fix this problem, make sure that the value the assertion expects is defined and matches the type mentioned in the error.
-- AngularJS Error Reference -- $compile -- ng:areq
Related
I have found similar question but not getting solution so i have post a question.
I have been implementing and displaying data from database in angular js, below is mu code.
index.php file:
<header>
<script type='text/javascript' src='local-path/js/angular.min.js?ver=4.9.5'></script>
<script type='text/javascript' src='local-path/js/angular-route.min.js?ver=4.9.5'></script>
<script type='text/javascript' src='local-path/js/scripts.js?ver=4.9.5'></script>
</header>
<div ng-controller="mycontrollermenu">
First Name: {{firstname}}
</div>
<div ng-view></div>
<footer></footer>
script.js:
var app = angular.module('wp',['ngRoute',' ']);
app.config(function($routeProvider, $locationProvider){
$routeProvider
.when('/', {
templateUrl : localized.partials + 'main.php',
controller : 'Main'
})
.when('/:slug', {
templateUrl: localized.partials + 'content.html',
controller: 'Content'
})
.otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
});
app.controller('Main',function($scope, $http, $routeParams){
$http.get('wp-json/wp/v2/posts/').success(function(res){
$scope.posts = res;
});
});
app.controller('Content',
['$scope', '$http', '$routeParams', function($scope, $http, $routeParams) {
$http.get('wp-json/wp/v2/posts/?slug=' + $routeParams.slug).success(function(res){
$scope.post = res[0];
});
}
]
);
app.filter('removeHTMLTags', function() {
return function(text) {
return text ? String(text).replace(/<[^>]+>/gm, '') : '';
};
});
app.controller('mycontrollermenu',function($scope){
$scope.firstname = "Menu 1";
});
I have added controller mycontrollermenu in to index and js file which is not working, and thow an error like
"Argument 'mycontrollermenu' is not a function, got undefined"
can any one guide me what i have doen wrong in "mycontrollermenu" controller?
Try creating a new .js file like MenuController.js and add the same
app.controller('mycontrollermenu',function($scope){
$scope.firstname = "Menu 1";
});
and in your index.html add <script type='text/javascript' src='MenuController.js'></script>
A couple of questions,
ng-app needs to be there on the root element. Wrap your HTML like <div ng-app="wp">...<div>
localized is a global variable? It is neither injected nor declared.
There is an empty string in the module definition. Forgot to include a dependency?
var app = angular.module('wp',['ngRoute',' ']);
Here I have a fiddle working with your code.
I am working through some Angular examples and got an interesting exception-scenario & was wondering why it happens.
The Scenario:
IT FAILS
- When I create my controller in a $(document)ready(function{ ... }) block
IT WORKS
- When I create my controller outright
Why?
I'm sure your not supposed to bring-in jQuery like this, but still, why does it fail?
In The Head:
<script type="text/javascript">
var appName = 'personal.web';
var application = angular.module(appName, ['ngRoute']);
application.config(function ($httpProvider, $routeProvider, $controllerProvider, $compileProvider, $filterProvider, $provide, $locationProvider) {
// REQUIRED: Enables "late" registration
application.register = {
controller: $controllerProvider.register,
directive: $compileProvider.directive,
filter: $filterProvider.register,
factory: $provide.factory,
service: $provide.service
};
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
});
application.run(function ($http) {
console.log(appName + ' is running');
});
</script>
In The Body:
<div class="container" ng-controller="HomeIndexController">
<div class="row">
<h3>Home Body</h3>
</div>
</div>
<div class="container">
<div class="row" ng-view></div>
</div>
At Page Bottom:
FAILS: A controller with this name is not registered
<script type="text/javascript">
$(document).ready(function () {
application.controller('HomeIndexController', function ($scope) {
var vm = this;
console.log('HomeIndexController');
});
}); </script>
WORKS
application.controller('HomeIndexController', function ($scope) {
var vm = this;
console.log('HomeIndexController');
});
Reason for it fails is $(document).ready, angular will register controllers, services and so on before rendering views. but here you are defining controller in document.ready which is too late that angular will throw error of cannot find controller.
It fails because document is ready after angular has started, so your app is looking for a component that does not exist yet. and it fails...
I wrote a simple Angular application and for my routing i used ui.router, but i am getting this error:
Argument 'loginController' is not a function, got undefined
modules.js:
(function () {
'use strict';
angular.module('account', ['ui.router']);
angular.module('app', ['account', 'ui.router']);
})();
routeConfig.js:
(function () {
'use strict';
var account = angular.module('account');
account.config(function ($stateProvider, $urlRouterProvider) {
// For any unmatched url
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('login', {
url: '/login',
templateUrl: '/app/components/account/login.html',
controller: 'loginController'
});
});
})();
account.js:
(function () {
'use strict';
var account = angular.module('account');
account.controller('loginController', ['$scope', loginController]);
function loginController($scope) {
$scope.Title = 'login';
};
});
index.html:
<!DOCTYPE html>
<html ng-app="app">
<head>
<title></title>
</head>
<body>
<div ui-view>
</div>
<script src="Scripts/jquery-1.9.1.js"></script>
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-ui-router.js"></script>
<script src="app/modules.js"></script>
<script src="app/routeConfig.js"></script>
<script src="app/components/account/account.js"></script>
</body>
</html>
login.html:
<h4>{{Title}}</h4>
I'm new to ui.router, and the error come from route config.
Thanks for any help
When you use injection, that's not the way to do it.
If your function is separate from account.controller, use $inject:
account.controller('loginController', loginController);
...
loginController.$inject = ['$scope'];
function loginController($scope) {
...
}
Direct injection is only used when the body is inside account.controller.
account.controller('loginController', ['$scope', function($scope) {
...
}]);
Also, it seems your account.js file has an invalid IIFE - (function(){...}); instead of (function(){...})();
I think you need to remove $scope from the controller declaration as given below:
(function () {
'use strict';
var account = angular.module('account');
account.controller('loginController', loginController);
function loginController($scope) {
$scope.Title = 'login';
};
});
I'm migrating from AngularJS 1.2.26 to 1.3.2 and receive an Error
Not the best error message to work out but it looks like it is saying that my controller is not defined? Can I no longer define controllers this way?
Error: error:areq
Bad Argument
Argument 'welcomeController' is not aNaNunction, got undefined
My index page is something like:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular-route.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular-sanitize.min.js"></script>
var myApp = angular.module('kioskApp', ['ngRoute','ngSanitize']).run(function($rootScope, $location, $timeout) {
$rootScope.authenticated = true;
});
myApp.config(function($routeProvider, $locationProvider, $sceDelegateProvider) {
$routeProvider
.when('/welcome', {
templateUrl : 'pages/welcome.php',
controller : 'welcomeController'
});
});
function welcomeController($rootScope, $scope, $http, $location) {
//stuff
}
My welcome page is something like:
<div ontouchmove="preventDrag(event)" ng-show="authenticated">
<!-- some images -->
</div>
You could use controller: welcomeController (without the quotes) to use it as a function. Otherwise, do something like myApp.controller('welcomeController', welcomeController).
You should also learn the syntax for dependency injection
I have an view (insight index.html) like that:
<body ng-app="mainApp" ng-controller="MainCtrl">
[...]
<div>{{status}} </div>
</body>
I start the App onDeviceReady:
angular.element(document).ready(function() {
angular.bootstrap(document);
});
I have this module:
var mainAppModul = angular.module('mainApp', ['ngRoute'])
.config(function ($routeProvider, $compileProvider) {
$routeProvider
.when('/', {
controller: MainCtrl,
template: '<h1> Main View {{ status }} </h1>'
});
$compileProvider.aHrefSanitizationWhitelist (/^\s*(https?|ftp|mailto|file|tel):/);
});
As far as I know, there are different ways to define a controller. One way is like that:
mainAppModul.controller('MainCtrl',['$scope', function ($scope)
{
$scope.status = "It works!";
}]);
The other one is like this:
function MainCtrl ($scope)
{
$scope.status = "It works!";
}
While the 1st Version results in [ng:areq] Argument 'MainCtrl ' is not a function, got undefined, the 2nd Version works fine.
Is there something I misunderstood in general?
ngRoute works in combination with ngView You won't need to specify the ng-controller in your templates, ngRoute takes care of that for you. When you have this:
var mainAppModul = angular.module('mainApp', ['ngRoute'])
.config(function ($routeProvider, $compileProvider) {
$routeProvider
.when('/', {
// controller: MainCtrl, // EDIT: needs to be a string of the controller name
controller: 'MainCtrl',
template: '<h1> Main View {{ status }} </h1>'
});
});
All you need is this:
<html ng-app="myApp">
<body>
<ng-view></ngview>
</body>
</html>
ngRoute will put the template of the specified route into ng-view and use the associated controller.
Note: ngRoute does not come with angular.js, you'll need the angular-route.js included as well.