How to load a service through shared.module in a lazy loaded ngModule only instantiated once though forRoot()

764 views Asked by At

How can I load a service through SharedModule as a singleton within a lazy loaded ngModule?

How can I load a service as a singleton within a lazy loaded ngModule?

I do have a SharedModule which provides several services like i18n and APIs. The services are own ngModules which provide their own forRoot functions. Now I'd like to load the Services from the SharedModule within a lacy loaded module with forRoot so that no new instance is created by dependency injection.

I tried things like the following, but nothing seems to work

shared.module.ts

import {I18nModule} from "./i18n/i18n.module";
import {ApiModule} from "./api/api.module";

@NgModule({
  exports: [
    I18nModule,
    ApiModule
  ]
}
export class SharedModule {
  static forRoot():ModuleWithProviders {{
    return {
      ngModule: SharedModule,
      providers: [ ... I18nModule.forRoot().providers, ... ApiModule.forRoot().providers ]
    };
  }
}

app.module.ts

@NgModule({
    declarations: [AppComponent],
    imports: [
        BrowserModule,
        routing,
        SharedModule.forRoot(),
    ],
    providers: [
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}

A goor resource to get into modules and forRoot / for child is http://blog.angular-university.io/angular2-ngmodule/

2

There are 2 answers

0
Manuel On

Chaining the the roots like in the questions works. Just ensure you load the SharedModule with SharedModule.forRoot() in root app.module and don't instantiate the services anywhere else. Angular goes down the ngModules till the root module.

import {I18nModule} from "./i18n/i18n.module";
import {ApiModule} from "./api/api.module";

@NgModule({
  exports: [
    I18nModule,
    ApiModule
  ]
}
export class SharedModule {
  static forRoot():ModuleWithProviders {{
    return {
      ngModule: SharedModule,
      providers: [ ... I18nModule.forRoot().providers, ... ApiModule.forRoot().providers ]
    };
  }
}
0
Kishin Karra On

Go ahead and add providedIn: 'root' in the injectable decorator of that service.

Service will load when: Any of the modules that uses the service loads. And the service will have a single instance.

Important: Do not add it to imports of the entry module(app.module.ts mostly). If you add it there, it will load with the first load of the app.