Angular has two main phases; the 'config' and the 'run phase.
Can be injected in config phase;
- Providers
- Constants
- Services in the
AUTO
module ($provide
and$injector
)
The $provide
service tells Angular how to create new services. Services are always defined by providers.
This is done using the provider
method on $provide
;
$provide.provider('example', function() {
this.$get = function() {
return service;
};
});
And this is placed within a config block;
module.config(function($provide) {});
Now we can inject a variable named 'example' into any injectable function (eg: controllers), then Angular will call the provider $get
function to return a new instance of the service.
Factory, service, value, etc are shortcuts to the above provider. They are syntactic sugar around providers.
Very simple
app.value('key', value);
Values cannot have things injected inside them.
Same as above, but can be accessed during the 'config' phase
- A factory can use other services / has dependencies
- Initialization code
- Delayed / lazy initialization
The same as a factory, but is instantiated with the 'new' operated when created
Its job is to create instances of services using code provided in $provide
It does this within a single $injector
service
Use the get
method to get a service;
const exampleService = $injector.get('example');
It will create the instance once, and then cache it.
This examples assumes you already have a service named ExampleNameService
within exampleName.service.js
, and you wish to create a provider for it.
Create this file within the same directory: exampleName.service.provider.js
The name of the provider should match the service, with the suffix of 'Provider', eg: ExampleNameServiceProvider
import { ExampleNameService } from 'exampleName.service.js';
export class ExampleNameServiceProvider {
constructor(injectAnotherProvider) {
'ngInject';
this.exampleSetting = 'default value';
}
setExampleSetting(exampleSetting) {
this.exampleSetting = exampleSetting;
}
$get(injectAnotherService) {
'ngInject';
return new ExampleNameService(injectAnotherService, this.exampleSetting);
}
}
Adjust the constructor of the service to accept additional settings provided by the provider.
Also remove the ngInject
string from the service constructor, as they have already been injected within the provider.
class ExampleNameService {
constructor(injectAnotherService, exampleSetting) {
this.exampleSetting = exampleSetting;
}
}
The Angular name should not contain the 'Provider' suffix.
Do not add the service to Angular. The service is now provided by the provider.
import { ExampleNameServiceProvider } from 'exampleName.service.provider.js';
.provider('ExampleNameService', ExampleNameServiceProvider)
function exampleConfig(ExampleNameServiceProvider) {
'ngInject';
ExampleNameServiceProvider.setExampleSetting('new value');
}
class ExampleController {
controller(ExampleNameService) {
'ngInject';
console.log(ExampleNameService.exampleSetting); // 'new value'
}
}