Creating and accessing a global constant in AngularJS - javascript

Does anyone know the best way to create and access a global constant is AngularJS?
I want to be able to doe something like:
app.constant('baseURL','http://www.baseurl.com');
and access it from any factory or controller.

Going for constant would be one of the better way as it has ability that we can access it inside the config level or in provider, so that we can take use of them to carry the config level settings.
For usage you could inject the same way as we do inject for service/factory or consider any dependency.
For making it more better you could use Object inside the your app.constant, so that it can carry multiple settings in it.
Constant
app.constant('configSettings', {
'baseUrl': 'http://www.baseurl.com',
'someElseSetting': 'settingValue'
//other setting will also be there.
});
Controller
app.controller('myCtrl', function($scope, configSettings){
//console.log(configSettings.baseUrl);
//you could use base URL here
});

Related

Global variable in AngularJS (good practice)

I'm looking for a pattern in order to have globals constant in my application. But not with a controller or a factory. (so not with app.constant() too)
I just want to set a variable but I didn't find something good.
I wanted to set this var in my rootScoop but without success.
with something like
myApp.run(function($rootScoop){
$rootScoop.global = {};
});
When I use that code, an arror occurs for nothing (transtateFilterProvider). When I delete this code, the translateService works,
I MUST have access in all html view, I don't want to always use a controller (useless in this case), I just want to set a global variable in rootScoop.
Thank you.
You are getting an error because it is :
$rootScope
And not
$rootScoop
Anyway, correct way to do this is to add a constant module to your app like :
angular.module('yourapp', []).constant('Constants', {
foo: 'bar'
});
But you'll have to call Constants in controllers.
If you use $rootScope, remember you will need to call $root.global in templates.

Define a constant that can be used in module/controller/etc. definition in angular

I would like to put module name, controller name etc. to string constants, so that I can easily change them if the need be (compared to fixing it in each and every file).
So I have this code:
angular
.module("app.admin.home")
.controller("HomeController", HomeController);
And I would like it have this (or similar):
angular
.module(moduleConstants.admin)
.controller(controllerConstants.adminHome, HomeController);
Is there a proper way to define this type of constants in Angular (ordinary injection does not work in this case). I guess I can create just global javascript constants, but maybe there is a better way of achieving this, some common way to define constants in angular. I have a strong C# background and it sounds stupid to me that constants need to be injected, they are not abstract code that can have different implementation, so it sounds wrong to inject it rather than just reference.
To avoid polluting the global name space, you could use a closure:
(function (moduleConstants, controllerConstants) {
angular
.module(moduleConstants.admin)
.controller(controllerConstants.adminHome, HomeController);
})({admin: "app.admin.home"},
{adminHome: "HomeController"});
According with the documentation, the right way of defining constants using angular js is using: Constants
This can be a simple implementation:
angular.module('config', [])
.constant('CONSTANT_YOU_NEED', {
name: 'test',
valueOfConst: '3.14'
});
But i guess you can't use this for modules or Controllers, but just passing to them

How to assign value to variable outside the function in $on AngularJS?

I am calling factory before we call $on , is there way to assign $scope.attestorObj.riskAssessmentRoleAsgnKey to roleAsgnKy value that is global variable.New to angularJS any help will be appreciated.
So far tried code...
main.js
var roleAsgnKy;
$scope.filesGridOptions = attestorConfig.getAttestorHistoryFile();
$scope.filesGridOptions.dataSourceattestorFactory.getFilesHistoryDataSource(roleAsgnKy);
$scope.$on('addEditAttest',function(s,attestorObj){
$scope.attestorObj = attestorObj;
$scope.attestorObj.riskAssessmentRoleAsgnKey = roleAsgnKy;
});
Based on your comment about it wanting to be a global variable you have two options
1) Setup a service/factory to store and access that variable. That way you can set and get it from anywhere in your app https://docs.angularjs.org/guide/services
2) Make it a variable within $rootScope, which you can inject into any controller and access or change from anywhere as well https://docs.angularjs.org/api/ng/service/$rootScope
It's generally considered best practice to use a service for your style of issue, and you can wrap any logic needed around the variable there as well.

Angular JS, Add Global Array or Object to Module. Recommended or not?

When creating an Angular Module one could essentially add global arrays or objects to the module. Like so..
var myApp = angular.module('myApp', ['myModule']);
myApp.run(function()
{
});
angular.module('myModule', [])
.run(function()
{
// global to module
var thisModule = angular.module('myModule');
thisModule.globalArray = [];
thisModule.globalObject = {};
});
So here's the question(s). Would it be a bad idea to do something like this? Is there anything in the documentation that recommends not doing this? And if so, why would or wouldn't you recommend not doing this?
Demo:
http://jsfiddle.net/hrpvkmaj/8/
In general, Angular goes to great lengths to avoid global state. You can observe this in the dependency injection system that the framework is based on. To use a component, you must inject it as a parameter that is wired up behind the scenes. The framework also has a powerful scoping system that allows for nice and easy encapsulation. Relying on global variables works against these systems.
In particular, it would be a bad idea to do something exactly like your code example because it isn't how Angular was designed to be used. You shouldn't be adding your own properties to Angular's module object. At the very least, you should be injecting the $rootScope object and adding your global variables to that.
app.run(function($rootScope)
{
$rootScope.globalArray = [];
$rootScope.globalObject = {};
});
From the Angular documentation:
Every application has a single root scope. All other scopes are descendant scopes of the root scope.
If you went this route, you could inject $rootScope wherever you need to use those global values.
However, the Angular team discourages using $rootScope.
Of course, global state sucks and you should use $rootScope sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on $rootScope, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.
There is another way of defining global values in Angular that is even preferable over using $rootScope: defining a value provider.
A value provider is the simplest kind of provider. It defines a single value that can be injected throughout your app.
You can define one like this:
app.value("myValue", {
someProp: 'Hello World'
});
Then you can inject the value wherever you need it like this:
app.controller("myController", function ($scope, myValue) {
$scope.someValue = myValue.someProp;
});
Here's a fiddle using a value provider to inject a global value.
In the end, any answer you get, including this one, will include some level of subjectivity. There are many ways to handle global values, but Angular provides some really convenient ways of using the framework to accomplish this.

Angular JS - How to safely retain global value "extracted" using a service

I need an object to be globally accessible all throughout my Angular application, and I've gladly put this object in a value service.
Unfortunately, this object is computed by another service, and I've not been able to inject myService into same value service.
ATM, I've acheived my goal with something like this:
global service code
app.service('myService', function() {
this.foo = function() {
// some code that returns an object
return computedObject
}
})
app.run(function ($rootScope, myService) {
$rootScope.global = {dbObject: myService.foo()}
})
And which I can use in any controller that pleases me by simply injecting $rootScope in it
However, I don't like the need of injecting the whole $rootScope wherever I need that damn object, and I trust is not much safe (or efficient?) either, since the team specifies
Of course, global state sucks and you should use $rootScope sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on $rootScope, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.
Conversely, don't create a service whose only purpose in life is to store and return bits of data.
Do you, perchance, happens to know any way I can inject a service into a service value?
Or maybe any other Angular best practice which I could exploit?
I forgot one very important notice
The computation of the object could be quite computational intense, so I absolutely don't want it to be recomputed everytime I move from page to page, or anything else really.
Ideally Using $rootScope for storing a few globally required values is totally ok. But if you are still adamant on using a module, I suggest you use a provider.
Make your 'myService' a provider and that will let you configure the variables in the service.
More info here
AngularJS: Service vs provider vs factory
You could use $broadcast to send the value from the value service to myService.
You would still need to inject $rootscope into each of the services, but from then on you could just inject myService around the rest of the app.
Reference here.
I need an object to be globally accessible all throughout my Angular application
I would use service. Since Service is singleton you can register the service to all your controllers and share any data over service.
Unfortunately, this object is computed by another service, and I've not been able to inject myService into same value service.
Just create one main service (Parent) and child service that will inherit the parent. (like abstract service in Java world).
Application.factory('AbstractObject', [function () {
var AbstractObject = Class.extend({
virtualMethod: function() {
alert("Hello world");
},
abstractMethod: function() { // You may omit abstract definitions, but they make your interface more readable
throw new Error("Pure abstract call");
}
});
return AbstractObject; // You return class definition instead of it's instance
}]);
Application.factory('DerivedObject', ['AbstractObject', function (AbstractObject) {
var DerivedObject = AbstractObject.extend({
virtualMethod: function() { // Shows two alerts: `Hey!` and `Hello world`
alert("Hey!");
this._super();
},
abstractMethod: function() {
alert("Now I'm not abstract");
}
});
return DerivedObject;
}]);
Now, we can add some logic into AbstractObject and continue use DerivedObject
Here is example Plunker

Categories

Resources