Passing a constant value among controllers angularjs - javascript

I have a constant value that is common throughout my project, among 2 of my modules- I want to have a design that I would have to only define it in one module and pass on the value to another module. How can I ?-
Module1 is like
var myApp = angular.module('myApp', ['ui.router']);
myApp.constant('constVar', 'http://45.26365.23/mydata/');
and Module2 is like
var Dashboardapp =angular.module('Dashboardapp', ['ui.router']);
Dashboardapp.constant('constVar', 'http://45.26365.23/mydata/');

For the record, the Google internal style guide says "do not define variables on the scope." (It actually explicitly says that). Note that means in particular, but not only, $rootScope (your code would be guaranteed to get kicked back in review if you did that, with very ugly "THIS IS BAD" comments).
Just define it at a higher level then both modules, typically at the app level (Angular 1.x defines a configurable place for constants in the app config API, you may want to look that up, this is useful because it actually enforces the constant). You can also just use a class defined in no module at all (just a top level class that you import and use statically), or you can define another module that you inject (which might be overkill for a few simple constants).

A naive approach would be to define the constant outside the modules:
var myConstant = 'http://45.26365.23/mydata/';
or maybe even better if you have more constants or other general data:
var myConfig = {
myConstant : 'http://45.26365.23/mydata/'
// other data
}
and then call it in the modules:
var myApp = angular.module('myApp', ['ui.router']);
myApp.constant('constVar', myConfig.myConstant);
var Dashboardapp =angular.module('Dashboardapp', ['ui.router']);
Dashboardapp.constant('constVar', myConfig.myConstant);
Other possibility would be to define it in only one module, which would be your main module, and inject it in the other modules:
var myApp = angular.module('myApp', ['ui.router']);
myApp.constant('constVar', 'http://45.26365.23/mydata/');
var Dashboardapp =angular.module('Dashboardapp', ['ui.router', 'myApp']);
Dashboardapp.constant('constVar', myApp.constant);
Instead of the last line you could just call the constant where ever it is needed.

You could always use the 'constant' that Angular comes with ...
import * as angular from 'angular';
export default angular
.module('app.constants.foo', [])
.constant('fooAction', Object.freeze({
name: value
}))
.name;
Then you inject your named constant. Thus it is accessible anywhere in the app (and more importantly immutable (mostly)).

Related

How to define controllers in separate files

Suppose that I have an SPA written via AngularJS 1.x.
It has a single app module defined like this:
var app = angular.module('app', ['ngAlertify', 'ngRoute', 'ui.bootstrap'])
I also have several controllers which are defined in separate *Ctrl.js-files. What is the appropriate way to define them?
I see two options here. The first one is
app.controller('LoginCtrl', function($scope) { /* ... */ });
and the second one is
angular.module('app').controller('LoginCtrl', function($scope) { /* ... */ });
Which one is better and most common-used practice? Is there any downsides of using either of them?
If I understand your question correctly then you wan to know different between
app.controller('LoginCtrl', function($scope) { /* ... */ });
vs
angular.module('app').controller('LoginCtrl', function($scope) { /* ... */ });
In above two in first method app is a global object which you declared somewhere i.e. in app.js like
var app = angular.module('app',[]);
In this case app is a global variable which will be accessible throughout your entire application. which I believe is not a good thing to use global variable
in our application.
In second method we are using global angular object to create a controller so that in this we will not be using global variable. In this case app.js will look like
(function(){
'use strict';
var app = angular.module('app', []);
....
....
....
....
})
In this case app variable will not be available anywhere apart from this file.
So I belive second method is better than first one.
My personal preference is to use app.controller('LoginCtrl', function($scope) { /* ... */ }); as this makes it easier to reuse the controller in another project with little to no changes, without those annoying module not found errors because you forgot to rename the module when reusing the file
I think that depends a bit on the personal style of writing. One thing is that while working with AngularJS 1.x.x you can have different styles of writing code, method stacking etc.
Personally, I prefer app.controller('LoginCtrl', function($scope) { /* ... */ }); mainly because you can easily preview your controller and distinguish it from thge module. Another bonus I see of having a clearly defined separate module is that you can easily check what includes you have ('ngAlertify', 'ngRoute', 'ui.bootstrap').
Most commonly used as far I have seen, even here on SO, is the method that I previously mentioned. Yet again this is something that is more reflective of personal style rather than strong pre-requirements of writing code. I hope that helps to some extend.
None of the above. The purpose of modules is to keep the application modular and not pollute global scope.
You can have var app = ... but this should be done inside IIFE once per file.
Another issue with modules is the precedence. If the application uses angular.module('app') module getter, the files should be loaded in specific order, in order for the module to be defined when it is retrieved in other files. This creates problems if they aren't, for example when they are concatenated in alphabetic order.
The solution is to use one module per file. This makes the application truly modular, independent of file loading order, also benefits testability. See also this answer for how this pattern supposed to work.
You can use module setter and getter methods for implementation of controllers in different file.
Suppose myApp.module.js
angular.module('myApp', []); //Setter method, registring module
In myApp.homeCtrl.js
var myApp = angular.module('myApp'); // getter method, getting the module already registered.
myApp.controller('homeCtrl', [function()]{ })
For more info check this https://toddmotto.com/angular-modules-setters-getters/
The second approach your are taking about is better because it uses the already created module and doesn't create the new module but with the first approach you are using global variable that is not recommended

Retrieving Constants\string values from a separate JS File

I am developing an Angular JS application.
I would like to know what is the best practice to include string values in our code.
I am planning to use another JS File which contains all the constant values. I will call this JS file in each and every JS(Controller) to refer the string values.
You can define constants in angular like
angular.module('moduleName',[]).constant('constName',string|object|array);
You can inject in directive or controller or wherever you want.
angular.module('moduleName',[]).directive('directiveName', ['constName', function(constName){...});
You have several options.
Global value. You can use your constants in form of the javascript object which would be globally accessible across the application. For example, your file could look something like this:
config = {
host: 'domain',
port: '1234'
};
Obvious disadvantage is that those values are not really a constants and can be easily changed, so it's error prone.
Angular config module. More reliable and cleaner option is to create a separate module to be used as a dependency for main app module. You would still have separate file for your constants but instead of some global variable this file would hold angular module with constant service. Something like this:
angular.module('app.config', []).constant('config', {
host: 'domain',
port: '1234'
});
Then in main application you would configure app like
angular.module('app', ['app.config']).config(function(config) {
// console.log(config);
});
Here is the sample code;
var app = angular.module('plunker', []);
app.constant('configs', {host:'localhost',port:8080});
app.controller('MainCtrl', function($scope, configs) {
$scope.name = configs.host;
});
here is demo plunker
Angular has a built in way of providing constants, e.g:
angular.module('foo', ['ngRoute']) // Your angularjs module
// Decide a name for the bucket of constants, then just declare the
// constants in turn as an object literal:
.constant("HTTP_CONSTANTS", {
"URL": "http://localhost",
"PORT": "80"
})
Then you can load it anywhere where you have access too you foo module using dependency injection, i.e.:
angular.module('foo')
.controller('bar', function (HTTP_CONSTANTS) {
... // Use HTTP_CONSTANTS.URL or HTTP_CONSTANTS.PORT, for example
})
Here's a good primer on using constants:
http://twofuckingdevelopers.com/2014/06/angularjs-best-practices-001-constants/
You can use factory for this purpose and inject this factory where ever you want these constants.
var app=angular.module('Myapp', []);
app.factory('ConstantService', function(){
var constant={temp:'c'};
var getConstants=function(){
return constant;
};
return{
constants:getConstants;
}
});
app.controller('MyController',['ConstantService' function (ConstantService){
var constant= ConstantService.constants;
}]);

Reusing directives for multiple modules

I would like to know what is the best way to reuse the same directive for multiple modules. In my mind i think directives are like DOM-modules, so the architecture of angular for this is a bit annoying of my point of view.
The way I'm doing it now is:
var mainapp = angular.module('MainApp');
mainapp.controller( ... );
var otherapp = angular.module('OtherApp');
otherapp.controller( ... );
And in other file i have my directive i want to use in this two controllers/modules
mainapp.directive('autoselect', function(){ ... });
But as you can see, I have to specify in what app I have to use it. If I want to use in both, do i have to copy twice the same code?
You can maintain a module that contains common (services, directives, values, constants etc.) and inject into each module.
angular.module('CommonApp',['OtherCommonModule1','OtherCommonModule2']).directive(..);
var mainapp = angular.module('MainApp', ['CommonApp']);
mainapp.controller( ... );
var otherapp = angular.module('OtherApp', ['CommonApp']);
otherapp.controller( ... );
No, you don't have to specify which app/module you need to use a directive in.
Let me explain:
In angularJS, everything is a module. For example, MainApp, OtherApp and even the autoselect directive is a module.
Each module can 'depend' on one or more modules.
So, here's how I would design the solution:
angular.module('com.example.mydirective', [])
.directive('autoselect', function() { ... });
angular.module('MainApp', ['com.example.mydirective']);
.controller(...);
angular.module('OtherApp', ['com.example.mydirective']);
.controller(...);
One thing I'd like to add: the square brackets that denote the dependency have a special significance.
angular.module('module-name', []); // this line tells angularJS to create a new module
angular.module('module-name'); // no brackets -- this asks angularjs to return a pre-existing module
Hope this helps

Access constant directly from Angular module

I have the following lines:
var app = angular.module('app', []);
app.constant("const", {
foo: "bar",
test: "123"
});
I would like to now access the information in constant directly from the module app. Something like this didn't work:
console.log(app.constant.const.foo);
I know you can inject constants into controllers, services etc and access the information but for my purposes, I would like to access them straight off the module.
Is the only way to access a registered constant is to inject it into a controller/service/etc?
Assuming, somehow, you want an access to the const outside the angularjs environment.
Then you have to retrieve it from an injector, and there are two ways you can get the injector:
Get the current injector of a running angularjs application like this:
var injector = angular.element(document).injector(); // assuming `ng-app` is on the document
injector.get('const');
Create a new injector from existing modules:
var injector = angular.injector(['ng', 'app']); // note the 'ng' module is required this way
injector.get('const');
Example Plunker: http://plnkr.co/edit/ld7LLlr94N7PiqnxY5zH
Hope this helps.
If you really want to access the constant directly, you could do:
var app = angular.module('app', []);
var app.constants = {foo: "bar", test: "123"};
app.constant("const", app.constants);
console.log(app.constants.foo);
But, I don't see a real benefit ;)

AngularJS defining angular.module() multiple times

What is the behaviour of calling angular.module('myModule') multiple times?
For example, I wish to define my routes and my directives in separate .js files.
Is this safe?
eg:
//routes.js
angular.module('app',['$strap'])
.config(function($routeProvider, $locationProvider) {
...
});
//directives.js
angular.module('app')
.directive('formInput', function() {
...
Also, what is the impact of defining the dependencies multiple times? Is this additive, or last-in-wins?
eg:
angular.module(name[, requires], configFn);
...
requires(optional) – {Array.=} – If specified then new module is being created. If unspecified then the the module is being retrieved for further configuration.
-- angular.module docs
I would interpret that as follows: you can only define the dependencies once -- the first time you call angular.module for a particular module. You can call angular.module() multiple times after that, but the requires option must not be specified.
You should only create your module once. According to the docs, if you create a module with a name that already exists, it will overwrite the previous one. (So last-in-wins.)
angular.module('app', []);
You can retrieve your module as many times as you like and in separate files if you wish. You will typically retrieve your module multiple times to declare services, controllers, directives, etc.
angular.module('app').service('myService', ...);
angular.module('app').controller('myController', ...);
angular.module('app').directive('myDirective', ...);
In the AngularJS docs on Modules, see the section called Creation versus Retrieval.
I'm new to angular, but this is my understanding: you create one module in each file with a namespaced module name, and in your main module you require those modules.
// in main app.js file
var app = angular.module('myapp',
['myapp.routers', 'myapp.directives', 'myapp.filters']);
// in filters.js
angular.module('myapp.filters', []).filter(....)
// in routers.js
angular.module('myapp.routers', []).router(....)
// in directives.js
angular.module('myapp.directives', []).directive(....)

Categories