Eager provider / service loader for Angular 2+
npm install angular-eager-provider-loader 
> Imporant: This package has been renamed to ngx-eager-provider-loader!
This module for Angular 4+ enables your application to eager load providers if necessary.
By default Angular loads all providers in a lazy manner, i.e. only whenever they are used by other components or
services that are instantiated.
While this is actually a good thing and is desirable for the majority of the cases, sometimes you might have a valid
reason to have your provider(s) loaded directly.
This is the case in particular for providers that play an active role in your application, but are never referenced by
other components or providers.
For more information when this is useful and the rationale for this package see the following article: Eager loading in Angular 2
To use this module in your application, you first have to install the NPM package, which can be done using the following
command:
```
npm install angular-eager-provider-loader --save
When installed, this package provides an UMD bundle (bundles/angular-eager-provider-loader.umd.js), that can be
referenced from the module loader used by your application.
For example when using SystemJS, add the following entries to the config file:
To the map option:``
'angular-eager-provider-loader': 'node_modules/angular-eager-provider-loader/bundles/'
To the packages option:``
'angular-eager-provider-loader': {
main: 'angular-eager-provider-loader.umd.js',
defaultExtension: 'js'
}
In addition to the UMD bundle, the package is also provided in ESM module format.
This format is more convenient to use when you want to make use of tree shaking.
The ESM bundle is provided in both ES5 (bundles/angular-eager-provider-loader.es5.js) and ES6bundles/angular-eager-provider-loader.js
().
After having installed the NPM package and updated the configuring of the module loader, you can use module within your
Angular application.
To enable eager loading for your provider(s), first find the @NgModule class in which the provider should be loaded.
Usually this is the same module in which the provider is defined, however it could be different module if you want to
eagerly load a provider that is defined in another module which you cannot modify.
Once you've found the module in which the provider should be loaded, import the EagerProviderLoaderModule:
`TypeScript
import { EagerProviderLoaderModule } from 'angular-eager-provider-loader';
@NgModule({
imports: [ EagerProviderLoaderModule ]
})
export class AppModule { / ... / }
`
By importing the EagerProviderLoaderModule your application will load all providers on startup that have beenEagerProviderLoaderModule
registered as eagerly loaded providers.
Although not strictly necessary, it is best to import this module in every module in which you mark providers for eager
loading.
This improves the reusability of those modules, since they don't depend on other modules to import the.
After having imported the EagerProviderLoaderModule, you need to define which providers you want to have loaded
eagerly.
This can be done using the following functions:
* eagerProviderRegistration(token: any): Provider - Registers a previously defined provider (usually defined inProvider
another module) for eager loading.
The result is a which you have to add the providers property of the NgModule decorator.eagerProvider(provider: Provider): Provider[]
* - Registers the specified provider and marks it for eager loading. Theproviders
result is an array consisting of two providers which need to be added to the property of the NgModuleeagerProviders(...providers: Provider[]): Provider[]
decorator. Use this function if you simultaneously wish to define a new provider and have it loaded eagerly.
* - Accepts an arbitrary number of providers which will be
returned as an array of providers that are marked for eager loading.
An example usage for each of these functions is shown in the code example below:
`TypeScript
import { OtherModule, providerFromOtherModule } from './modules/other-module/index';
import { RouteLogger, MyService, AwesomeMyServiceImpl, AnotherCoolService, BadAssService } from './index';
import {
EagerProviderLoaderModule,
eagerProviderRegistration,
eagerProvider,
eagerProviders,
} from 'angular-eager-provider-loader';
@NgModule({
imports: [
OtherModule,
EagerProviderLoaderModule
],
providers: [
// Mark the provider identified by the token providerFromOtherModule for eager loading.OtherModule
// Note that the provider is listed in the providers of the , so we only have
// to mark it for eager loading.
eagerProviderRegistration(providerFromOtherModule),
// Defines the provider RouteLogger and marks it for eager loading. Note that the expression
// below is equivalent to: ...[RouteLogger, eagerProviderRegistration(RouteLogger)]
...eagerProvider(RouteLogger),
// Defines three providers and marks them for eager loading.
...eagerProviders(
{ provide: MyService, useClass: AwesomeMyServiceImpl },
AnotherCoolService,
BadAssService
)
]
})
export class AppModule { / ... / }
`
Unfortunately when using AoT you cannot use function calls for the @NgModule metadata, hence it is not possible to useeagerProvider*
the functions to generate the eager provider registrations.EAGER_PROVIDER
This means you'll have to define these registration entries manually in the providers list of your module.
To do so, first import the token.UserService
With this token you can register a provider for eager loading.
This is illustrated for the in the following example:
`TypeScript
import { EagerProviderLoaderModule, EAGER_PROVIDER } from 'angular-eager-provider-loader';
import { UserService } from './shared/user.service';
@NgModule({
imports: [ EagerProviderLoaderModule ],
providers: [
UserService,
{ provide: EAGER_PROVIDER, useValue: UserService, multi: true }
]
})
export class AppModule { / ... / }
`
Note that you have to define the provider twice: once as you would normally define it and once as the value of multi
provider for the EAGER_PROVIDER token.useValue
If you omit the normal provider definition, then Angular will complain about not having a provider for whatever value
you specified in the property.useValue
It is important to use the property and not the useClass property, since this will result in a runtime DImulti
error, which the eager provider loader cannot prevent.
Also make sure to always set the property to true.
The eager provider loader package has support for lazy loaded modules.
However, before using eager provider loading for lazy loaded modules ask yourself whether it actually makes sense that
the provider should only be loaded when the module itself is loaded.
In most cases I expect that the provider must be loaded on application startup anyway.
If so, you can simply move the eager loading registration to the module that is being used to bootstrap the application
(or to another imported module).
If you still feel that you need eager provider loading for a lazy loaded module, then you can use it in the same way as
you would for modules that get loaded on application startup.
Just don't forget to import the EagerProviderLoaderModule within these lazy loaded modules.
Note that there is a small difference for eager loaded providers compared to normal providers which are defined in lazy
loaded modules.
Normal providers for lazy loaded modules might be instantiated multiple times by Angular itself, e.g. when changing
routes back and forth to lazy loaded routes.
The eager provider loader, however, makes sure that providers marked for eager loading within these lazy loaded modules
will only be instantiated once.
In case your service does not get loaded on application startup, check the following:
* You have marked the provider for eager loading with one of the following functions: eagerProviderRegistration,eagerProvider, or eagerProviders.EAGER_PROVIDER
When using AoT, instead of these functions, add a multi provider for the token.eagerProviderRegistration
* If you manually mark a provider for eager loading, either using the function or theEAGER_PROVIDER token, make sure that provider itself is also added to the providers list of the module (or importedEagerProviderLoaderModule
modules).
* The provider is marked for eager loading in a lazy loaded module that simply hasn't been loaded yet.
* At least one of the modules that gets loaded on application startup adds to the importEagerProviderLoaderModule`.
list.
If you use lazy loaded modules, then those also need to import