I'm using AngularJS and Django together, so I apply the recipe found here to reconfigure Angular's template delimiters:
angular.module("some module name").config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
I have to re-apply this piece to each module, only changing the "some module name" string. Is there a way to define this piece of configuration once, and then cleanly require and inject it into a module at the module's definition site?
Since $interpolateProvider is a provider, any change to it will affect not only the current module but also all the modules that depends on it.
You can, for example, define a "config" module and add it as dependency to other modules:
angular.module('config', []).config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
And on the other modules:
angular.module('module1', ['config']);
angular.module('module2', ['config']);
Demo plunker
Related
Am new to angularjs and given a codebase to add angular-moment (moments.js) to a module.
The module is defined is as follows:
angular.module("xyz", ["ngRoute",
"ui.bootstrap",
"infinite-scroll",
"uiGmapgoogle-maps",
"googlechart"],
function($interpolateProvider) {
$interpolateProvider.startSymbol("[[");
$interpolateProvider.endSymbol("]]");
})
.factory("principal", principal)
.factory("authorization", authorization)
.factory("pingService", abc)
When i add angularMoment just after "googlechart" i get a "unpr" angular error. I did include both moments.js and angular-moments.js in my html.
I need to use javascript moments lib in my angular code.
Please help.
thanks
You haven't included 'angularMoment' in your module as dependency.
Do like following :
angular.module("xyz", ["ngRoute",
"ui.bootstrap",
"infinite-scroll",
"uiGmapgoogle-maps",
"googlechart","angularMoment"],
function($interpolateProvider) {
$interpolateProvider.startSymbol("[[");
$interpolateProvider.endSymbol("]]");
})
.factory("principal", principal)
.factory("authorization", authorization)
.factory("pingService", abc)
And make sure , you have included the angular-moment.js file in your index.html
I hope this helps. Do let me know in case of any query
You don't need to add any directive to use momentjs in your project, reference it just like any other script in your SPA main page an use it on any controler.
The only benefit of loading it via a directive is having it declared as a dependence, and the possibility of mocking it for tests, if you don't care about this, just use it as you would do without Angular.
Please note this is not a duplicate of:How to inject module and make it accesible to entrie angular app
I have a module (app.config) that I would like to inject into my entire app.
The module needs to be accessible within all other modules and submodules(modules inside modules) injected into myApp
For example, my app looks like this:
angular.module('myApp', [
'app.config',
'module#1',
'module#2',
'module#3',
'module#4'
])
.config...
/////////////////////////////////
Here's app.config
angular.module('app.config', []).
constant('NAME1', 'Name1').
constant('NAME2', 'Name2');
////////////////////
I want 'app.config' injected in such a way that it should be accesible in module#500 which is not directly a dependecy of 'myApp', but a dependecy of module#1 - which, in turn, is a dependecy of myApp.
module#1 is defined as such (as shown,module#500 is a dependecy of module#1):
angular.module('module#1', [
'module#500',
'module#501',
'module#502',
...
]);
Here's my problem:
angular.module('module#500', []).
service('serviceOne', serviceOne);
function ServiceOne($http, NAME1) {
var service = {
getMyProfile: function(){return $http.get('api/' + NAME1);}
};
return service;
}
Problem - I get an error-> Uncaught Error: [$injector:unpr] Unknown provider: NAME1Provider <-NAME1 <- serviceOne But I thought I injected it to the entire app???
I don't want to add module#500 directly as dependency to 'myApp' I wan't to leave module#500 as a dependecy of module#1. And I want to leave module#1 as a dependency of myApp
I don't want to individually inject app.config to each and every module either. Any other solutions?
I don't want to individually inject app.config to each and every
module either. Any other solutions?
I don't know what solution you could be expecting? With this line: angular.module('module#500', []). how is module#500 going to know about anything else, it has nothing given to it. Maybe I'm misunderstanding something here.
edit, as I've just read your post and comments from yesterday: I think you're not understanding dependency-injection properly. It only goes one way, module#1 has access to module#500, but module#500 doesn't have access to module#1. It has to be that way: How could you unit-test module#500 if it has some behavior that depends on module#1, which is not mentioned anywhere in its code?
I'm guessing your project doesn't really call for so many modules, if they all depend on the same config variables. Those factories and services that depend on the config variables should be in the same module with it. That is proper compartmentalization and will make your life easier in the long run.
If you don't want to make myApp dependent on app.config (though it would be the right thing to do because its submodules depend on it), you can load config module with manual bootstrapping
angular.bootstrap(document, ['myApp', 'app.config']);
instead of ng-app="myApp".
You forgot to inject NAME1 in your ServiceOne service.
eg: function ServiceOne($http, NAME1)
I have a global module 'app' which include two other modules 'app.core' and 'app.service'. This is basic settings. Inside the two sub module I can access the constant from both two modules. However I cannot access constants declared in 'app' within 'app.core' or 'app.service'.
Also I use angular.bootstrap to delay my initialization because I need to retrieve a config from server. But after receiving the config I do angular.module('app').constant('config', config); So the constant should be well defined..
LAst point, inside the 'app' module config I can access the config constant.
Any idea ?
'app' module constants declaration
angular.module('app',[
'app.core',
'app.service'
])
.module('app')
.constant('foo', 'foo')
'app.core' constants
angular
.module('app.core')
.constant('core', 'core');
In 'app.service' I can get core constant
angular.module('app.services',[]).config(function($injector){
console.log($injector.get('core'));
})
But I cannot retrieve 'app' constant
angular.module('app.services',[]).config(function($injector){
console.log($injector.get('foo'));
})
Will crash
In both configurations you are trying to access a constant defined within a separate module, but then not defining that module as a dependency. How, for example, can app.services have access to foo when foo is defined on a module which requires app.services in the first place?
The reason that core is available to app.services despite this is because you have listed the dependencies in such an order when defining app that angular happens to have loaded app.core prior to app.services. The order of the defined dependencies, however, should not matter.
In order to correct this, you should consider refactoring your modules so that there is no inherent circular dependency. For example, consider making your config a module in itself and inject it into the dependent services:
angular.module('app', ['app.core', 'app.services'])
angular.module('app.config', [])
.constant('foo', 'foo')
angular.module('app.core', ['app.config'])
.config(function(foo) {})
angular.module('app.services', ['app.config'])
.config(function(foo) {})
Note also that using the injector to get constants is un-necessary as they can be injected directly during the configuration stage.
I'm developing simple AngularJS (I'm quite new with Angular) application and I encountered problem that js are loading in wrong order. Below there are relevant (I hope) snippets of my app.
index.html
(...)
<script data-main="scripts/main.js" src="scripts/require.js"></script>
(...)
main.js
requirejs.config({
baseUrl: 'scripts',
paths: {
angular: '../../bower_components/angular/angular',
jquery: 'jquery',
domReady: 'domReady',
'jquery.scrollTo': '../../bower_components/jquery.scrollTo/jquery.scrollTo',
},
shim: {
jquery: {deps: ['domReady']},
'jquery.scrollTo': {deps: ['jquery']},
angular: {deps: ['jquery.scrollTo'], exports: 'angular'}
},
packages: []
});
requirejs(['angular', 'domReady', 'jquery', 'app', 'scripts', 'jquery.scrollTo'], function(angular, domReady) {
'use strict';
domReady(function() {
angular.bootstrap(document, ['myApp']);
});
});
app.js
define('app', ['angular', 'domReady', 'jquery', 'jquery.scrollTo'], function (angular) {
return angular.module('myApp', []);
});
scripts.js
require(['domReady', 'jquery', 'jquery.scrollTo'], function(domReady, $) {
domReady(function() {
console.log('scripts.run');
});
});
I assumed that loading order should be following:
main
domReady
jquery
jquery.scrollTo
angular
scripts
app
But in real loading order is following:
The most strange for me is why scripts.js is loaded before jquery.js and jquery.scrollTo.js if require statement define that it is dependent on domReady, jquery and jquery.scrollTo?
I suggest to remove jquery completely from your code (if its possible for you) and requirejs. AngularJS has great dependency injection module which you could use to support timing of loaded parts.
Also - you could try to inline ng-app attribute inside html code insted of invoking angular via boostrap call, than you won't need "domReady".
If you can, please tell something more about your app so we can give you better response on availible solutions.
deitch's statement regarding loading order is correct. RequireJS will guarantee that the order in which the factory functions of your modules (factory == the callback you give to define) are executed will respect the dependencies specified. As far as the order in which modules are fetched the only thing you can be sure is that a module will be fetched before its factory function is executed but RequireJS otherwise has the freedom to fetch modules in any order.
In the case you are showing us, note how the modules that are first fetched after main are those which do not have a shim configuration defined for them. Modules with a shim configuration require a bit more processing from RequireJS and thus follow a different code path.
While we're at it, a few bizarre things in your code:
A path configuration that just repeats the name of the module does nothing. For instance, jquery: 'jquery'. You could remove such path specifications.
You have require at the top level of scripts.js. You should have define there instead.
Your call to define in app.js specifies a module name (1st parameter to define). Leave the module name out.
You give a jQuery a shim configuration. jQuery calls define. Giving a shim to a module that calls define is likely to result in undefined behavior. Don't do this.
I'm building an app with MEAN.JS and I'm trying to use a controller from another module. I've found that I can do this with dependency injection:
angular.module(‘MyModule’, [‘Dependency’]);
But the way modules are created in MEAN.JS is:
ApplicationConfiguration.registerModule('MyModule');
And I can't just pass a second parameter to registerModule. So, how should I do this? Do I have to use both methods? Am I doing it wrong?
Example
I want to add a new model: Campaign. Campaigns are created by admins only, but can be seen by the "campaign owner" (another User). The create campaign form should list available Users, so the admin can select the one that's going to be the "owner" of that Campaign.
The problem is, the create campaign form is controlled by CampaignsController, how can I list Users? I've used another controller (UsersController) and thats the problem, it is undefined because we are in the Campaign module.
EDIT:
The problem was grunt autorestarting the app incorrectly:
I moved the controller from one module (folder) to another, but grunt was still trying to load it from the old path, and thus failing: Controller not found. I thought the problem was dependency injection, but you only have to close grunt (Ctrl+C) and run it again. Problem solved.
Anyways, thanks for the answer #gilBirman cause it is correct: there is no need to inject anything with MEANJS.
MEAN.js makes all the modules registered via registerModule available to all other modules in your app by adding it as a dependency to the main app called mean. Here's the part of the MEAN.js source code that does this:
var applicationModuleName = 'mean';
....
// Add a new vertical module
var registerModule = function(moduleName) {
// Create angular module
angular.module(moduleName, []);
// Add the module to the AngularJS configuration file
angular.module(applicationModuleName).requires.push(moduleName);
};
So you're on the right track, however it sounds like you are trying to inject a controller. However, in angular, controllers are not injectable. You can inject services, factories, values, and constants.
First create your own module for example:
angular.module('app.controllers', []) - angular module with controllers.
then add controller to that module:
angular.module('app.controllers', [])
.controller('dashboard.admin.account.controller', ['$scope', ($scope) { .... }]);
then create global module which will bind to your markup:
angular.module('app', [
'app.controllers'
'ui.router',
'ngAnimate'
]);
then bootstrap your global module to markup:
domReady(function () {
angular.bootstrap(document, ['app']);
});
Now you can use your controller.