I am trying to dependency inject a module into another—the former is simply an empty module.
angular.module('module1', []);
angular.module('module2', [])
.controller('Module2Ctrl', ['module1', '$scope', function (module1, $scope) {
$scope.expression = 'hello!';
}]);
HTML:
<html ng-app="module2">
<body ng-controller="Module2Ctrl">
<h1>{{expression}}</h1>
</body>
</html>
I'm getting the dreaded Unknown provider: module1Provider <- module1 <- Module2Ctrl message.
What's going on? I believe everything is defined as it should be—though module1 has no definitions, I can't find information anywhere on what would stop this from working.
Plnkr: http://plnkr.co/edit/goMVFRNuPgG6iIpGYI1Y?p=preview
Thanks :-)
You inject providers (such as factories, services, ...), not modules. Remove the module1 injection and it will work. What you're thinking of doing is probably declaring module2 as a module dependency of module1:
angular.module('module1', ['module2']);
and then ng-app="module".
angular.module can not injected inside a controller,Only one angular.module can be injected inside another module.
angular.module('module2', ['module1'])
You should never do that angular. Only angular components are inject-able like service,controller, factory, filter, provider,etc.
For initializing angular on page you could do angular.bootstrap
angular.bootstrap(document,["module2"])
Related
I've been trying to set up basic AngularJS functionality for a project but have been hitting a brick wall when it comes to including angular-route. Both are version 1.4.8. I'm currently using gulp-require to concatenate my JS, here's my main javascript file
// =require ../components/jquery/dist/jquery.min.js
// =require ../components/angular/angular.js
// =require ../components/angular-route/angular-route.js
$(document).ready(function() {
// =require app/app.js
}); // Doc ready is done!
And my app.js file
var app = angular.module('myApp', ['ngRoute']);
app.controller("ctrl", ["$scope", 'ngRoute', function($scope) {
$scope.test = "It works!";
}]);
I've checked and all the files are concatenating properly. The ng-app and ng-controller attributes are on my HTML file. I've tried adding and removing the ngRoute injection and switching the order of the files but to no avail. It's frustrating since I used Angular 1.4.5 in almost the exact same way without these issues popping up but I can't replicate the same here even when going back. But the {{test}} variable in my HTML is still not rendering, and basic operations like {{2 + 3}} aren't either.
EDIT: here is the link to the original error message I'm currently receiving: http://tinyurl.com/zx3k85f
EDIT 2: The parts of my HTML code that's calling the app and the controller:
<html lang="en" ng-app="myApp">
<body ng-controller="ctrl">
</body>
</html>
I'm using nunjucks for HTML dynamic generation, although I've changed the syntax for this so it doesn't conflict with Angular's double curly braces.
You can't inject module as dependency inside controller, you should remove 'ngRoute' from the controller DI inline array.
app.controller("ctrl", ["$scope", , function($scope) {
Update
Basically the real problem is you are loading your angular component script using requirejs(lazily), so while you are having ng-app="myApp" with module name start looking for myApp module, and the module has not loaded therefore it throws an error .
So I'd recommend you to don't use ng-app directive to start angular on page load. Instead you should wait until all the scripts related to angular loaded, & then to bootstrap angular app lazily using angular.bootstrap method.
Code
$(document).ready(function() {
requirejs(["app/app.js"], function(util) {
angular.bootstrap(document, ['myApp']);
});
});
ngRoute is a provider that needs to be configured in the module config section before being used. Using it within a controller does not make any sense. Here the version that will work:
angular.module('myApp', ['ngRoute']);
angular.module('myApp').controller("ctrl", ["$scope",function($scope) {
$scope.test = "It works!";
}]);
Moreover, you need to call your module using directive ng-app=myapp in the html element where you plan to render your app.
Looking at the angular documentation for controller there's something that confuses me. Let's say someone does this:
angular.module('foo').controller('controller1', ['$scope', function($scope) {
});
and:
<div ng-app='app' ng-controller='controller1'>
</div>
How does angular know that 'controller1' resides in module 'foo'?
And furthermore if someone does this in addition:
angular.module('bar').controller('controller1', ['$scope', function($scope) {
});
Which one will angular chose now?
When you declare ng-app here:
<div ng-app='app' ng-controller='controller1'>
</div>
Angular will look for a module definition with the name app. Something like this:
angular.module('app', []); // notice the []
Inside the second parameter [] array, Angular wants the dependent modules. So, in order to include controller1 from foo module, you would do this:
angular.module('app', ['foo']);
And from the bar module:
angular.module('app', ['bar']);
In each of these, there is only a single controller1 named controller.
So, what happens when you register both the foo and bar modules? I would think that the last one wins. So, if you define app to be:
angular.module('app', ['foo', 'bar']);
Then, the bar module's controller1 will overwrite the name controller1 inside the injector.
So, there is no built-in mechanism that allows for the same name to be applied across modules. Because of this, you can employ naming schemes to make sure that the controller is unique:
angular.module('bar').controller('bar.controller1', ['$scope', function($scope) {
});
How does angular know that 'controller1' resides in module 'foo'?
At the time that Angular is resolving controller1, it doesn't know what module it is in. Once the module is a dependent (on the module defined in ng-app), all of the controllers (in all modules) are only resolved off of their names.
Angular doesn't really know where the controller comes from. Your application includes either foo or bar and then controller1 is registered.
If you include both foo and bar controller1 is from whatever module you included last.
Let's say I have a simple module:
angular.module('Platform', []);
And let's say I have another module:
angular.module('PlatformProductA', []);
Is there an Angular function I can call from JavaScript that will inject module 'PlatformProductA' as a dependency into module 'Platform', as if module 'Platform' had been defined like this:
angular.module('Platform', ['PlatformProductA']);
In other words, after a module has been defined, I need to inject another module into it as a dependency.
EDIT:
I'm not sure how, but this seems to work:
angular.module('Platform', []);
angular.module('PlatformProductA', []);
angular.module('Platform').requires.push('PlatformProductA');
Angular somehow sees that 'PlatformProductA' has been injected?
Yes there is $injector, which allows dynamic injection
angular.module('Platform', [$injector], function(){ // don't remember exact syntax
$scope.myModule = $injector.get('PlatformProductA');
});
May be it's trivial question, but for AngularJS newbie it's a matter ^_^
What I'm trying to originally achieve is to make a dynamically inserted tag (by jQuery) with ng-click directive to work. I've searched and found that I've to get AngularJS Injector, then compile that code. So here it is the simplest form of the injector code which is NOT working for me, what's wrong with it?
Note #1: The dynamically inserted tag with ngDirective is done outside AngularJS scope.
angular.module('simpleExample', [])
.run(
[ '$rootScope',
function ($rootScope) {
$rootScope.test = "Test";
}]);
console.log(angular.injector(['simpleExample']));
// console.log(angular.injector(['simpleExample']).$compile('Text'));
http://jsfiddle.net/Zx8hr/6/
The ng module
angular.bootstrap automatically adds the ng module to the dependencies when used (manually or with ngApp)
$rootScope / $compile services are part of the ng module.
You need to use injector.invoke if you want these services.
You should probably use angular in more traditional ways.
Try this:
angular.module('simpleExample', ['ng']);
angular.injector(['simpleExample'])
.invoke(['$rootScope','$compile',
function($rootScope, $compile){
var elm = $compile('Text')($rootScope);
$rootScope.someFunctionOnRootScope = function(){
alert("Hello there!");
}
angular.element(document.body).append(elm);
}]);
How do I use underscore library inside angularjs controllers?
On this post: AngularJS limitTo by last 2 records
somebody suggested to assign an _ variable to the rootScope so that the library will be available to all the scopes within the app.
But I'm not clear where to do it. I mean should it go on the app module declaration? i.e:
var myapp = angular.module('offersApp', [])
.config(['$rootScope', function($rootScope) { }
But then where do I load underscore lib? I just have on my index page the ng-app directive and script reference to both the angular-js and underscore libs?
index.html:
<head>
</head>
<body ng-app="offersApp">
...
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="scripts/vendor/angular.js"></script>
<script src="scripts/vendor/underscore.js"></script>
...
How do I achieve this?
When you include Underscore, it attaches itself to the window object, and so is available globally.
So you can use it from Angular code as-is.
You can also wrap it up in a service or a factory, if you'd like it to be injected:
var underscore = angular.module('underscore', []);
underscore.factory('_', ['$window', function($window) {
return $window._; // assumes underscore has already been loaded on the page
}]);
And then you can ask for the _ in your app's module:
// Declare it as a dependency of your module
var app = angular.module('app', ['underscore']);
// And then inject it where you need it
app.controller('Ctrl', function($scope, _) {
// do stuff
});
I have implemented #satchmorun's suggestion here:
https://github.com/andresesfm/angular-underscore-module
To use it:
Make sure you have included underscore.js in your project
<script src="bower_components/underscore/underscore.js">
Get it:
bower install angular-underscore-module
Add angular-underscore-module.js to your main file (index.html)
<script src="bower_components/angular-underscore-module/angular-underscore-module.js"></script>
Add the module as a dependency in your App definition
var myapp = angular.module('MyApp', ['underscore'])
To use, add as an injected dependency to your Controller/Service and it is ready to use
angular.module('MyApp').controller('MyCtrl', function ($scope, _) {
...
//Use underscore
_.each(...);
...
I use this:
var myapp = angular.module('myApp', [])
// allow DI for use in controllers, unit tests
.constant('_', window._)
// use in views, ng-repeat="x in _.range(3)"
.run(function ($rootScope) {
$rootScope._ = window._;
});
See https://github.com/angular/angular.js/wiki/Understanding-Dependency-Injection about halfway for some more info on run.
You can also take a look at this module for angular
https://github.com/floydsoft/angular-underscore
If you don't mind using lodash try out https://github.com/rockabox/ng-lodash it wraps lodash completely so it is the only dependency and you don't need to load any other script files such as lodash.
Lodash is completely off of the window scope and no "hoping" that it's been loaded prior to your module.
you can use this module -> https://github.com/jiahut/ng.lodash
this is for lodash so does underscore