AngularJS's module.constant
does not define a constant in the standard sense.
While it stands on its own as a provider registration mechanism, it is best understood in the context of the related module.value
($provide.value
) function. The official documentation states the use case clearly:
Register a value service with the $injector, such as a string, a number, an array, an object or a function. This is short for registering a service where its provider's $get property is a factory function that takes no arguments and returns the value service. That also means it is not possible to inject other services into a value service.
Compare this to the documentation for module.constant
($provide.constant
) which also clearly states the use case (emphasis mine):
Register a constant service with the $injector, such as a string, a number, an array, an object or a function. Like the value, it is not possible to inject other services into a constant.
But unlike value, a constant can be injected into a module configuration function (see angular.Module) and it cannot be overridden by an AngularJS decorator.
Therefore, the AngularJS constant
function does not provide a constant in the commonly understood meaning of the term in the field.
That said the restrictions placed on the provided object, together with its earlier availability via the $injector, clearly suggests that the name is used by analogy.
If you wanted an actual constant in an AngularJS application, you would "provide" one the same way you would in any JavaScript program which is
export const π = 3.14159265;
In Angular 2, the same technique is applicable.
Angular 2 applications do not have a configuration phase in the same sense as AngularJS applications. Furthermore, there is no service decorator mechanism (AngularJS Decorator) but this is not particularly surprising given how different they are from each other.
The example of
angular
.module('mainApp.config', [])
.constant('API_ENDPOINT', 'http://127.0.0.1:6666/api/');
is vaguely arbitrary and slightly off-putting because $provide.constant
is being used to specify an object that is incidentally also a constant. You might as well have written
export const apiEndpoint = 'http://127.0.0.1:6666/api/';
for all either can change.
Now the argument for testability, mocking the constant, is diminished because it literally does not change.
One does not mock π.
Of course your application specific semantics might be that your endpoint could change, or your API might have a non-transparent failover mechanism, so it would be reasonable for the API endpoint to change under certain circumstances.
But in that case, providing it as a string literal representation of a single URL to the constant
function would not have worked.
A better argument, and likely one more aligned with the reason for the existence of the AngularJS $provide.constant
function is that, when AngularJS was introduced, JavaScript had no standard module concept. In that case, globals would be used to share values, mutable or immutable, and using globals is problematic.
That said, providing something like this through a framework increases coupling to that framework. It also mixes Angular specific logic with logic that would work in any other system.
This is not to say it is a wrong or harmful approach, but personally, if I want a constant in an Angular 2 application, I will write
export const π = 3.14159265;
just as I would have were I using AngularJS.
The more things change...
AppSettings
class should be abstract andAPI_ENDPOINT
member should bereadonly
. – Gratian