I have a requirement wherein a single page contains lot of data. All these data are though different but needs to be displayed in one page only (with vertical scroll).
I have made various collapsible divs on my page and they are controlled usig ng-if for avoiding too much of DOM.
Initially for prototype, I had JS logics for all these divs in one controller. However, now I am following a different approach wherein I want one controller for the page and various child controller for the collapsible divs.
I kept one object each for a div in page controller and made several other controller on my main module (app.js). I expect each of them to be child of pageCtrl and as such I should be accessing data for each div in 'pageCtrl`.
However, this is not working. No errors though on consoles, but no divs are visible.
My structure is as:
<body ng-app ="mainModule">
<div ng-controller ="pageCtrl">
<div ng-controller = "collapse1Ctrl" ng-include="collapse1.tpl" ng-if="collapse1reqd">
<div ng-controller = "collapse2Ctrl" ng-include="collapse2.tpl" ng-if="collapse2reqd">
<div ng-controller = "collapse3Ctrl" ng-include="collapse3.tpl" ng-if="collapse3reqd">
<div ng-controller = "collapse4Ctrl" ng-include="collapse4.tpl" ng-if="collapse4reqd">
<div ng-controller = "collapse5Ctrl" ng-include="collapse5.tpl" ng-if="collapse5reqd">
</div>
JS is like:
angular.module("mainModule", []);
angular.module("mainModule").controller("pageCtrl", pageCtrlFn);
angular.module("mainModule").controller("collaspse1Ctrl", collaspse1CtrlFn);
angular.module("mainModule").controller("collaspse2Ctrl", collaspse2CtrlFn);
angular.module("mainModule").controller("collaspse3Ctrl", collaspse3CtrlFn);
angular.module("mainModule").controller("collaspse4Ctrl", collaspse4CtrlFn);
angular.module("mainModule").controller("collaspse5Ctrl", collaspse5CtrlFn);
Rest assured, all templates and conditions are at correct places.
Since my code as such is too large, I am avoiding to post it currently. May be I will post a similar fiddle soon.
But currently I wonder if is there any problem with having such a structure at all ??
Based on the OP's question and the problem's faced here's an example demo on how nested controllers work and how the scope behaves.
HTML looks like
<body ng-app="scopeInheritance">
<div class="spicy">
<div ng-controller="MainController">
<p>Good {{timeOfDay}}, {{name}}!</p>
<p>{{display.showName}} - {{age}} --> New Age - {{display.age}}</p>
<input type="text" ng-model="name">
<button ng-click="resetTime()">CHANGE</button>
<div ng-controller="ChildController">
<p>Good {{timeOfDay}}, {{name}}!</p>
<button ng-click="setTime()">SET</button>
<input type="text" ng-model="display.showName"> Age - {{age}}
<input type="text" ng-model="age">
<button ng-click="setAge()">Change Age</button>
<div ng-controller="GrandChildController">
<p>Good {{timeOfDay}}, {{name}}!</p>
</div>
</div>
</div>
</div>
JS looks like below
(function(angular) {
'use strict';
var myApp = angular.module('scopeInheritance', []);
myApp.controller('MainController', ['$scope', function($scope) {
$scope.timeOfDay = 'morning';
$scope.files ='';
$scope.name = 'Nikki';
$scope.display={};
$scope.display.showName ='Vikram';
$scope.age ='20';
// $scope.display.age ='20';
$scope.resetTime = function(){
$scope.timeOfDay = 'chaged day';
};
}]);
myApp.controller('ChildController', ['$scope', function($scope) {
$scope.name = 'Mattie';
$scope.$parent.timeOfDay ='';
$scope.setTime = function(){
$scope.timeOfDay = 'new day';
};
$scope.setAge = function(){
$scope.display.age ='25';
};
}]);
myApp.controller('GrandChildController', ['$scope', function($scope) {
$scope.timeOfDay = 'evening';
$scope.name = 'Gingerbread Baby';
}]);
})(window.angular);
This example is an extension of Angular Js org nested controllers doc's based example.
Better to wrap all your templates and controllers into components and hide them from outside controller
<component1 ng-if="req1"></component1>
<component2 ng-if="req2"></component2>
<component3 ng-if="req3"></component3>
and use ControllerAs of course.
I am trying to get AngularJS to run in my .jsp page with the simplest app copied directly from W3s example
UPDATE: I'm trying to use angular in a Liferay portlet, so here is the extent of my code in view.jsp
<%
/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*/
%>
<%# taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</div>
<script type='text/javascript'>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
</script>
However, as soon as I attempt to use my Controller + $scope object, the app breaks and I get the error
Failed to instantiate module myApp due to:
Error: [$injector:modulerr] http://errors.angularjs.org/1.5.6/$injector/modulerr?p0=n...)
at Error (native)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:6:412
at https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:40:134
at q (https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:7:355)
at g (https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:39:222)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:39:391
at q (https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:7:355)
at g (https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:39:222)
at db (https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:43:246)
at Ac.c (https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:21:19
I cannot figure out why this is. Any ideas?
For some reason, from your error, it looks like the code thinks you are trying to inject 'a'.
If possible, I recommend you put this in a separate script, and wrap in an IIFE:
app.js:
(function(){
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
})();
And then include it in your HTML:
<script src="app.js"></script>
I am following a video tutorial video for Angular JS and started the topic of using a controller as syntax. The example I am working on yields a different result from the one in the tutorial, however. My code (below) outputs the following error:
angular.js:13550 Error: [ng:areq] Argument 'ParentController' is not a function, got undefined
I am confused as to why this is happening since I copied the code verbatim from the tutorial and still get the error while the tutorial's code output seems fine.
HTML
<body>
<div ng-controller="ParentController">
<p>This is the parent: {{ parentMessage }}</p>
<div ng-controller="FirstChild">
<p>My parent is: {{ parentMessage }}</p>
<p>The first child is: {{ firstMessage }}</p>
</div>
<div ng-controller="SecondChild">
<p>My parent is: {{ parentMessage }}</p>
<p>The second child is: {{ secondMessage }}</p>
</div>
</div>
</body>
JS
angular.model('myApp').controller('ParentController', ['$scope', function($scope) {
$scope.parentMessage = 'What she said.';}]);
angular.model('myApp').controller('FirstChild', ['$scope', function($scope) {
$scope.firstMessage = 'I want my mother.';}]);
angular.model('myApp').controller('SecondChild', ['$scope', function($scope) {
$scope.secondMessage = 'I want my father.';}]);
The reason the error is appearing is because the HTML code isn't able to find the ParentController, FirstChild and SecondChild functions as functions in the JS code. The reason this is bothering me is because when I attempt a similar parent/child JS/HTML code pair then the error doesn't appear.
HTML
<body>
<div ng-controller="First">
<input type="text" ng-model="model.name">
<p>This is the first controller: {{model.name}}</p>
</div>
<div ng-controller="Second">
<input type="text" ng-model="model.name">
<p>This is the second controller: {{model.name}}</p>
</div>
</body>
JS
angular.module('myApp').service('SharedService',function(){
return {name: 'Uncle Alvin'};});
angular.module('myApp').controller('First',['$scope', 'SharedService', function($scope, SharedService){
$scope.model = SharedService;}]);
angular.module('myApp').controller('Second',['$scope', 'SharedService', function($scope, SharedService){
$scope.model = SharedService;}]);
I am not convinced that using shared services is the reason the latter pair of code works while the former doesn't. I want to know what is causing the HTML to not recognize the ng-controllers in the first instance and how I should go about modifying the pair to make them recognizable.
I apologize if this post is redundant to another topic that I couldn't find on my own. If it is, feel free to link the most original/helpful posting of this issue.
The reason for controllers not working in the first module is,
(i) Not model it is module
angular.module('myApp')
and it is easy if you dont declare it thrice, declare once and add the controllers.
var myApp= angular.module('myApp', []);
myApp.controller('ParentController', ['$scope', function($scope) {
$scope.parentMessage = 'What she said.';}]);
myApp.controller('FirstChild', ['$scope', function($scope) {
$scope.firstMessage = 'I want my mother.';}]);
myApp.controller('SecondChild', ['$scope', function($scope) {
$scope.secondMessage = 'I want my father.';}]);
Here is a simple example on how to do it.
Took this example from w3schools
First Name:
Last Name:
Full Name: {{firstName + " " + lastName}}
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</div>
This is a long shot, but has anyone seen this error before? I am trying to add 'Transporters' using express, angular and mongoDB. I get this error whenever I access a page ruled by the transporters controller:
Error: [ng:areq] http://errors.angularjs.org/1.2.12/ng/areq?p0=TransportersController&p1=not%20aNaNunction%2C%20got%20undefined
at Error (native)
at http://localhost:3000/lib/angular/angular.min.js:6:450
at tb (http://localhost:3000/lib/angular/angular.min.js:18:360)
at Pa (http://localhost:3000/lib/angular/angular.min.js:18:447)
at http://localhost:3000/lib/angular/angular.min.js:62:17
at http://localhost:3000/lib/angular/angular.min.js:49:43
at q (http://localhost:3000/lib/angular/angular.min.js:7:386)
at H (http://localhost:3000/lib/angular/angular.min.js:48:406)
at f (http://localhost:3000/lib/angular/angular.min.js:42:399)
at http://localhost:3000/lib/angular/angular.min.js:42:67
The transporters controller looks like this:
'use strict';
angular.module('mean.transporters').controller('TransportersController', ['$scope', '$routeParams', '$location', 'Global', 'Transporters', function ($scope, $routeParams, $location, Global, Transporters) {
$scope.global = Global;
$scope.create = function() {
var transporter = new Transporters({
name: this.name,
natl_id: this.natl_id,
phone: this.phone
});
transporter.$save(function(response) {
$location.path('transporters/' + response._id);
});
this.title = '';
this.content = '';
};
$scope.remove = function(transporter) {
if (transporter) {
transporter.$remove();
for (var i in $scope.transporters) {
if ($scope.transporters[i] === transporter) {
$scope.transporters.splice(i, 1);
}
}
}
else {
$scope.transporter.$remove();
$location.path('transporters');
}
};
$scope.update = function() {
var transporter = $scope.transporter;
if (!transporter.updated) {
transporter.updated = [];
}
transporter.updated.push(new Date().getTime());
transporter.$update(function() {
$location.path('transporters/' + transporter._id);
});
};
$scope.find = function() {
Transporters.query(function(transporters) {
$scope.transporters = transporters;
});
};
$scope.findOne = function() {
Transporters.get({
transporterId: $routeParams.transporterId
}, function(transporter) {
$scope.transporter = transporter;
});
};
}]);
In my views I call the list and create methods. They generate the above error
I got this from the angular docs for ng:areq though still can't figure what's going on
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 truthy.
Here's the view that calls the controller public/views/transporters/list.html:
<section data-ng-controller="TransportersController" data-ng-init="find()">
<ul class="transporters unstyled">
<li data-ng-repeat="transporter in transporters">
<span>{{transporter.created | date:'medium'}}</span> /
<h2><a data-ng-href="#!/transporters/{{transporter._id}}">{{transporter.name}}</a></h2>
<div>{{transporter.natl_id}}</div>
<div>{{transporter.phone}}</div>
</li>
</ul>
<h1 data-ng-hide="!transporters || transporters.length">No transporters yet. <br> Why don't you Create One?</h1>
</section>
Transporters service code:
angular.module('transporterService', [])
.factory('Transporter', ['$http', function($http){
// all return promise objects
return {
get: function(){
return $http.get('/api/transporters');
},
create: function(transporterData){
return $http.post('/api/transporters', transporterData);
},
delete: function(id){
return $http.delete('/api/transporters/'+id);
}
};
}]);
I experienced this error once. The problem was I had defined angular.module() in two places with different arguments.
Eg:
var MyApp = angular.module('MyApp', []);
in other place,
var MyApp2 = angular.module('MyApp', ['ngAnimate']);
I've gotten that error twice:
1) When I wrote:
var app = module('flapperNews', []);
instead of:
var app = angular.module('flapperNews', []);
2) When I copy and pasted some html, and the controller name in the html did not exactly match the controller name in my app.js file, for instance:
index.html:
<script src="app.js"></script>
...
...
<body ng-app="flapperNews" ng-controller="MainCtrl">
app.js:
var app = angular.module('flapperNews', []);
app.controller('MyCtrl', ....
In the html, the controller name is "MainCtrl", and in the js I used the name "MyCtrl".
There is actually an error message embedded in the error url:
Error: [ng:areq]
http://errors.angularjs.org/1.3.2/ng/areq?p0=MainCtrl&p1=not%20a%20function%2C%20got%20undefined
Here it is without the hieroglyphics:
MainCtrl not a function got undefined
In other words, "There is no function named MainCtrl. Check your spelling."
I ran into this issue when I had defined the module in the Angular controller but neglected to set the app name in my HTML file. For example:
<html ng-app>
instead of the correct:
<html ng-app="myApp">
when I had defined something like:
angular.module('myApp', []).controller(...
and referenced it in my HTML file.
you forgot to include the controller in your index.html. The controller doesn't exist.
<script src="js/controllers/Controller.js"></script>
I had same error and the issue was that I didn't inject the new module in the main application
var app = angular.module("geo", []);
...
angular
.module('myApp', [
'ui.router',
'ngResource',
'photos',
'geo' //was missing
])
Check the name of your angular module...what is the name of your module in your app.js?
In your TransportersController, you have:
angular.module('mean.transporters')
and in your TransportersService you have:
angular.module('transporterService', [])
You probably want to reference the same module in each:
angular.module('myApp')
I had this error too, I changed the code like this then it worked.
html
<html ng-app="app">
<div ng-controller="firstCtrl">
...
</div>
</html>
app.js
(function(){
var app = angular.module('app',[]);
app.controller('firstCtrl',function($scope){
...
})
})();
You have to make sure that the name in module is same as ng-app
then div will be in the scope of firstCtrl
The same problem happened with me but my problem was that I wasn't adding the FILE_NAME_WHERE_IS_MY_FUNCTION.js
so my file.html never found where my function was
Once I add the "file.js" I resolved the problem
<html ng-app='myApp'>
<body ng-controller='TextController'>
....
....
....
<script src="../file.js"></script>
</body>
</html>
:)
I've got that error when the controller name was not the same (case sensitivity!):
.controller('mainCOntroller', ... // notice CO
and in view
<div class="container" ng-controller="mainController"> <!-- notice Co -->
I got this same error when I included the entire controller file name in the Routes like this:
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'home.html',
controller: 'mainController.js'
})
.when('/portfolio', {
templateUrl: 'portfolio.html',
controller: 'mainController.js'
})
});
When it should be
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'home.html',
controller: 'mainController'
})
.when('/portfolio', {
templateUrl: 'portfolio.html',
controller: 'mainController'
})
});
Angular takes certain things you name like the app and controller and expounds on them in directives and across your app, take care to name everything consistently and check for this when debugging
I know this sounds stupid, but don't see it on here yet :). I had this error caused by forgetting the closing bracket on a function and its associated semi-colon since it was anonymous assigned to a var at the end of my controller.
It appears that many issues with the controller (whether caused by injection error, syntax, etc.) cause this error to appear.
This happened to me when I have multiple angular modules in the same page
I encountered this error when I used partial views
One partial view had
<script src="~/Scripts/Items.js"></script>
<div ng-app="SearchModule">
<div ng-controller="SearchSomething" class="col-md-1">
<input class="searchClass" type="text" placeholder="Search" />
</div>
</div>
Other had
<div ng-app="FeaturedItems" ng-controller="featured">
<ul>
<li ng-repeat="item in Items">{{item.Name}}</li>
</ul>
</div>
I had them in same module with different controller and it started working
I had the same error in a demo app that was concerned with security and login state. None of the other solutions helped, but simply opening a new anonymous browser window did the trick.
Basically, there were cookies and tokens left from a previous version of the app which put AngularJS in a state that it was never supposed to reach. Hence the areq assertions failed.
There's also another way this could happen.
In my app I have a main module that takes care of the ui-router state management, config, and things like that. The actual functionality is all defined in other modules.
I had defined a module
angular.module('account', ['services']);
that had a controller 'DashboardController' in it, but had forgotten to inject it into the main module where I had a state that referenced the DashboardController.
Since the DashboardController wasn't available because of the missing injection, it threw this error.
In my case I included app.js below the controller while app.js should include above any controller like
<script src="js/app.js"></script>
<script src="js/controllers/mainCtrl.js"></script>
I had done everything right other than setting controller in $stateProvider. I used filename rather than variable name.
Following code is wrong:
formApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('management', {
url: '/management',
templateUrl: 'Views/management.html',
controller: 'Controllers/ManagementController.js'
});
and this is the right approach;
formApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('management', {
url: '/management',
templateUrl: 'Views/management.html',
controller: 'ManagementController'
});
Make sure you noticed;
controller: 'ManagementController'
And for those who are curious about my controller file ManagementController.js, it looks like the this;
formApp.controller('ManagementController', ['$scope', '$http', '$filter', '$state',function(scope, http, filter, state) {
scope.testFunc = function() {
scope.managementMsg = "Controller Works Fine.";
};
}]);
For those who want a quick-start angular skeleton for above example check this link https://github.com/zaferfatih/angular_skeleton
The error will be seen when your controller could not be found in the application. You need to make sure that you are correct using values in ng-app and ng-controller directives
This happened to me when using ng-include, and the included page had controllers defined. Apparently that's not supported.
Controller loaded by ng-include not working
I have made a stupid mistake and wasted lot of time so adding this answer over here so that it helps someone
I was incorrectly adding the $scope variable(dependency)(was adding it without single quotes)
for example what i was doing was something like this
angular.module("myApp",[]).controller('akshay',[$scope,
where the desired syntax is like this
angular.module("myApp",[]).controller('akshay',['$scope',
// include controller dependency in case of third type
var app = angular.module('app', ['controller']);
// first type to declare controller
// this doesn't work well
var FirstController = function($scope) {
$scope.val = "First Value";
}
//Second type of declaration
app.controller('FirstController', function($scope) {
$scope.val = "First Controller";
});
// Third and best type
angular.module('controller',[]).controller('FirstController', function($scope) {
$scope.val = "Best Way of Controller";
});