I am using goldenlayout with angualrJS. I am facing below exception:
Error: ng:btstrpd App Already Bootstrapped with this Element
on execution of this line of code
myGoldenLayout.on('initialised', function () {
angular.bootstrap(angular.element('#layoutContainer')[0], ['app']);
});
The reason is, I have already ng-app in my HTML so how can I register golden layout when I already have ng-app?
https://github.com/codecapers/golden-layout-simple-angular-example/issues/1
Well, the official Golden Layout docs recommend using manual bootstrap, but if you want to keep using ng-app, then you have to make sure that your components (templates) are compiled by Angular (via $compile). Here's an example of how to do that:
angular.module('someApp') // your main module name here
.run(function ($compile, $rootScope) {
myLayout.registerComponent('template', function( container, state ){
var templateHtml = $('#' + state.templateId).html();
var compiledHtml = $compile(templateHtml)($rootScope);
container.getElement().html(compiledHtml);
});
myLayout.on( 'initialised', function() {
$rootScope.$digest(); // Golden Layout is done, let Angular know about it
});
});
// somewhere...
myLayout.init();
Basically, the main difference from the example in the repository you provided is that instead of just appending raw HTML, we $compile it with Angular, so now it knows to set up bindings and keep the html updated.
This should allow you to keep using ng-app instead of manual bootstrap.
I am writing a sample application using angularjs. i got an error mentioned below on chrome browser.
Error is
Error: [ng:areq] http://errors.angularjs.org/1.3.0-beta.17/ng/areq?p0=ContactController&p1=not%20a%20function%2C%20got%20undefined
Which renders as
Argument 'ContactController' is not a function, got undefined
Code
<!DOCTYPE html>
<html ng-app>
<head>
<script src="../angular.min.js"></script>
<script type="text/javascript">
function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}
</script>
</head>
<body>
<h1> modules sample </h1>
<div ng-controller="ContactController">
Email:<input type="text" ng-model="newcontact">
<button ng-click="add()">Add</button>
<h2> Contacts </h2>
<ul>
<li ng-repeat="contact in contacts"> {{contact}} </li>
</ul>
</div>
</body>
</html>
With Angular 1.3+ you can no longer use global controller declaration on the global scope (Without explicit registration). You would need to register the controller using module.controller syntax.
Example:-
angular.module('app', [])
.controller('ContactController', ['$scope', function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}]);
or
function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}
ContactController.$inject = ['$scope'];
angular.module('app', []).controller('ContactController', ContactController);
It is a breaking change but it can be turned off to use globals by using allowGlobals.
Example:-
angular.module('app')
.config(['$controllerProvider', function($controllerProvider) {
$controllerProvider.allowGlobals();
}]);
Here is the comment from Angular source:-
check if a controller with given name is registered via $controllerProvider
check if evaluating the string on the current scope returns a constructor
if $controllerProvider#allowGlobals, check window[constructor] on the global window object (not recommended)
.....
expression = controllers.hasOwnProperty(constructor)
? controllers[constructor]
: getter(locals.$scope, constructor, true) ||
(globals ? getter($window, constructor, true) : undefined);
Some additional checks:-
Do Make sure to put the appname in ng-app directive on your angular root element (eg:- html) as well. Example:- ng-app="myApp"
If everything is fine and you are still getting the issue do remember to make sure you have the right file included in the scripts.
You have not defined the same module twice in different places which results in any entities defined previously on the same module to be cleared out, Example angular.module('app',[]).controller(.. and again in another place angular.module('app',[]).service(.. (with both the scripts included of course) can cause the previously registered controller on the module app to be cleared out with the second recreation of module.
I got this problem because I had wrapped a controller-definition file in a closure:
(function() {
...stuff...
});
But I had forgotten to actually invoke that closure to execute that definition code and actually tell Javascript my controller existed. I.e., the above needs to be:
(function() {
...stuff...
})();
Note the () at the end.
I am a beginner with Angular and I did the basic mistake of not including the app name in the angular root element. So, changing the code from
<html data-ng-app>
to
<html data-ng-app="myApp">
worked for me. #PSL, has covered this already in his answer above.
I had this error because I didn't understand the difference between angular.module('myApp', []) and angular.module('myApp').
This creates the module 'myApp' and overwrites any existing module named 'myApp':
angular.module('myApp', [])
This retrieves an existing module 'myApp':
angular.module('myApp')
I had been overwriting my module in another file, using the first call above which created another module instead of retrieving as I expected.
More detail here: https://docs.angularjs.org/guide/module
I just migrate to angular 1.3.3 and I found that If I had multiple controllers in different files when app is override and I lost first declared containers.
I don't know if is a good practise, but maybe can be helpful for another one.
var app = app;
if(!app) {
app = angular.module('web', ['ui.bootstrap']);
}
app.controller('SearchCtrl', SearchCtrl);
I had this problem when I accidentally redeclared myApp:
var myApp = angular.module('myApp',[...]);
myApp.controller('Controller1', ...);
var myApp = angular.module('myApp',[...]);
myApp.controller('Controller2', ...);
After the redeclare, Controller1 stops working and raises the OP error.
Really great advise, except that the SAME error CAN occur simply by missing the critical script include on your root page
example:
page: index.html
np-app="saleApp"
Missing
<script src="./ordersController.js"></script>
When a Route is told what controller and view to serve up:
.when('/orders/:customerId', {
controller: 'OrdersController',
templateUrl: 'views/orders.html'
})
So essential the undefined controller issue CAN occur in this accidental mistake of not even referencing the controller!
This error might also occur when you have a large project with many modules.
Make sure that the app (module) used in you angular file is the same that you use in your template, in this example "thisApp".
app.js
angular
.module('thisApp', [])
.controller('ContactController', ['$scope', function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}]);
index.html
<html>
<body ng-app='thisApp' ng-controller='ContactController>
...
<script type="text/javascript" src="assets/js/angular.js"></script>
<script src="app.js"></script>
</body>
</html>
If all else fails and you are using Gulp or something similar...just rerun it!
I wasted 30mins quadruple checking everything when all it needed was a swift kick in the pants.
If you're using routes (high probability) and your config has a reference to a controller in a module that's not declared as dependency then initialisation might fail too.
E.g assuming you've configured ngRoute for your app, like
angular.module('yourModule',['ngRoute'])
.config(function($routeProvider, $httpProvider) { ... });
Be careful in the block that declares the routes,
.when('/resourcePath', {
templateUrl: 'resource.html',
controller: 'secondModuleController' //lives in secondModule
});
Declare secondModule as a dependency after 'ngRoute' should resolve the issue. I know I had this problem.
I was getting this error because I was using an older version of angular that wasn't compatible with my code.
These errors occurred, in my case, preceeded by syntax errors at list.find() fuction; 'find' method of a list not recognized by IE11, so has to replace by Filter method, which works for both IE11 and chrome.
refer https://github.com/flrs/visavail/issues/19
This error, in my case, preceded by syntax error at find method of a list in IE11. so replaced find method by filter method as suggested https://github.com/flrs/visavail/issues/19
then above controller not defined error resolved.
I got the same error while following an old tutorial with (not old enough) AngularJS 1.4.3. By far the simplest solution is to edit angular.js source from
function $ControllerProvider() {
var controllers = {},
globals = false;
to
function $ControllerProvider() {
var controllers = {},
globals = true;
and just follow the tutorial as-is, and the deprecated global functions just work as controllers.
New to angular and have a page in which I have the app and controller defined. After the controller, I am trying to display a value I get back from a Node Rest call (which I get correctly). If I put {{1+1}} i get a value... I do not get a value for {{test}} or {{stock.symbol}}. I do see them in the scope variable in firebug ....
Not sure what I am doing wrong with the definition of the module. Any help would be appreciated! Code snippets below ...
HTML
=====
<html lang="en" ng-app="tradingSystem">
..
..
{% block content %}
{% include "includes/carousel.html" %}
<div class="container" ng-controller="StockListCtrl">
<h3>Test: {{ test }} </h3>
<h3>Symbol: {{ stock.symbol }}</h3>
{% block content %}
{% include "includes/carousel.html" %}
<div class="container" ng-controller="StockListCtrl">
<h3>Test: {{ test }} </h3>
<h3>Symbol: {{ stock.symbol }}</h3>
App.JS
=======
'use strict';
/* App Module */
var tradingSystem = angular.module('tradingSystem', [
'ngRoute',
'tradingSystemAnimations',
'tradingSystemControllers',
'tradingSystemFilters',
'tradingSystemServices'
]);
controllers.js
=============
'use strict';
/* Controllers */
var app = angular.module('tradingSystem', []);
app.controller('LoginCtrl', ['$scope', 'User', function($scope, User) {
$scope.authenticate = function (user)
{
$scope.user = User.authenticate({emailAddress: user.emailAddress, password: user.password});
alert("Received " + $scope.user);
};
}]);
app.controller('StockListCtrl', ['$scope', '$http', function($scope, $http) {
$scope.test = 'This is a test';
$http.get('/api/stocks')
.success(function (stocks) {
if (!stocks) {
console.log("No results from api/stocks service ");
}
else
{
$scope.stocks = stocks;
console.log("Results: " + stocks);
console.log("Stocks Fetched: " + $scope.stocks.length)
$scope.stock = stocks[0];
console.log("Scope: " + $scope);
alert(stocks[0].symbol);
console.log($scope);
}
})
.error(function (reason) {
alert(reason);
});
}]);
The problem was related to using Swig as my rendering engine with Express. Once I added swig.setDefaults({ varControls: ['<%=', '%>'] }); // or anything besides ['{{', '}}'] to change the defaults, the page rendered the AngularJS variables.
As Alex C mentions you are re-declaring the app module in the controllers file - as the docs note at https://docs.angularjs.org/api/ng/function/angular.module - if you are wanting to retrieve an existing module you need to leave off the second parameter, eg.
angular.module('myModule', []); //creates a new module
angular.module('myModule'); //retrieves an existing module
So given that you have already declared your tradingSystem module and assigned it to a global variable (not the best approach for larger apps, but ok for a small example) in your controller.js you need to drop var app = angular.module('tradingSystem', []); and have
tradingSystem.controller('LoginCtrl', etc.
but you do have tradingSystemControllers as a dependency of your tradingSystem module, so maybe in your controllers file you meant to put:
var tradingSystemControllers = angular.module('tradingSystemControllers', []);
EDIT: 20/7/2014
As far as setting up for larger applications goes, not my tips or best practice, I am just following what other leaders in this area are suggesting and it is working for me for now ;-)
I think that https://github.com/ngbp/ngbp is a good example of an Angular app structure broken down by module, with all files (module js, templates, less, unit tests) related to a module in the same folder. ngbp also has a good automated workflow for compiling both a dev and production build with karma testing, jshint, etc. built in. There are lots of angular seed/boilerptlate projects around now - not saying the ngbp is the best as I haven't looked at them all in detail - but the approach of putting all related module files together in the module folder is a good one I think, and the approach suggested by the Angular team now - https://docs.google.com/a/core-ed.ac.nz/document/d/1XXMvReO8-Awi1EZXAXS4PzDzdNvV6pGcuaF4Q9821Es/pub
In relation to using
var tradingSystem = angular.module(
that I mentioned in my first answer - given that you have easy access to any angular modules via
angular.module('myModule')
assigning a module to a global variable doesn't have any huge advantage, and potentially clutters the global name space in a large app. I like the approach put forward by a couple of others which is to use an IIFE to encapsulate each module a bit better - details here - http://caughtexceptions.blogspot.co.nz/2014/07/angular-module-setup.html
To this end I have modified the ngbp build process slightly to use grunt-wrap to wrap each module definition in its own IIFE as part of build process.
This is an ng-animate noob question. I looked at the example at angularjs.org and copied the html and css into my project. I added ngAnimate to the dependencies of my app. But it's not working. Upon (un)checking, the correct div is displayed, but no animation.
I tried adding 'ngAnimate' to the dependencies of my Controller, but then I get this error: http://errors.angularjs.org/1.2.11/$injector/unpr?p0=ngAnimateProvider%20%3C-%20ngAnimate
i notice that the example app has ng-app="ngAnimate" in the body tag, I thought adding ngAnimate to my dependencies would do the same.
Can anyone help?
here is the fiddle : enter link description here (unfortunatley angularjs not working)
var app = angular.module('my', [
'ngAnimate',
'my.controllers'
]);
var controllers = app.module('my.controllers', []);
controllers.controller('MyController', function($scope) {
$scope.checked = true;
});
upgrading from angularjs 1.2.11 to 1.3.0-beta7 did the trick.
I have a scenario where I need to dynamically load an Angular JS application. I have based the code on this:-
https://stackoverflow.com/a/15252490/1545858
Now, I have code that works really well with angular js 1.1.5, but in 1.2.1, no such luck.
Here is the JS code:-
$("#startMeUp").click(function() {
// Make module Foo
angular.module('Foo', []);
// Make controller Ctrl in module Foo
angular.module('Foo').controller('Ctrl', function($scope) {
$scope.data = {};
$scope.data.name = 'KDawg';
$scope.destroy = function() {
$scope.$destroy();
$('#Ctrl').remove();
};
$scope.$on("$destroy", function () {
console.log("EXTERMINATE");
});
});
// Load an element that uses controller Ctrl
$('<div ng-controller="Ctrl" id="Ctrl"> ' +
'<input type="text" ng-model="data.name"></input>' +
'{{data.name}}' +
'<button ng-click="destroy()">Destroy Me</button></div>').appendTo('#container');
// Bootstrap with Foo
angular.bootstrap($('#Foo'), ['Foo']);
});
And here is the HTML:-
<button id="startMeUp">Start Me Up!</button>
<div id="Foo">
<div id="container">
</div>
</div>
Now, if you start and destroy and start again with angular js 1.1.5, everything works fine, but in angular js 1.2.1 it does not work in on the second start. Any thought on how to make it work in 1.2.1?
Here is the js fiddle:-
http://jsfiddle.net/Y9wj2/
As charlietfl says, you don't need to bootstrap more than once. In fact, using angular.js 1.2.1, the error generated that breaks everything is telling you exactly that:
[ng:btstrpd] App Already Bootstrapped with this Element ''
You should think carefully about whether you really need this controller to be dynamic. If you can just use something like ng-include to load the extra content then you will have a much easier time and no need to worry about compiling the content.
If you find you really do need to take this HTML and load it from outside of angular context then you can use the $compile service. Bootstrap the app once somewhere first, preferably using ng-app and grab the injector.
var injector = angular.bootstrap($('#Foo'), ['Foo']);
or
<div id="Foo" ng-app="Foo"></div>
var injector = $('#Foo').injector();
Now you can insert the HTML however you like and then compile and link it using
injector.invoke(['$compile', '$rootScope', function($compile, $rootScope) {
$compile(insertedJqLiteNode)($rootScope);
});