Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 Lazy Loading Service being Instantiated Twice

I just switched my application over to be lazy-loaded today.
I have a SharedModule that exports a bunch of services. In my AppModule, I import SharedModule because AppComponent needs access to a few of the shared services.

In another module FinalReturnModule, I import SharedModule. In one of my services, I put a console.log('hi') in the constructor.

When the app first loads, I get hi to the console. Whenever I navigate to a page within the FinalReturnModule I get hi again. Obviously, since there are two instances, nothing's working correctly since the modules aren't able to communicate.

How can I stop the service from being instantiated twice?

EDIT: Background, the app is built using angular-cli.

Current versions:

angular-cli: 1.0.0-beta.24
node: 6.9.1
os: win32 ia32
@angular/common: 2.4.1
@angular/compiler: 2.4.1
@angular/core: 2.4.1
@angular/forms: 2.4.1
@angular/http: 2.4.1
@angular/platform-browser: 2.4.1
@angular/platform-browser-dynamic: 2.4.1
@angular/router: 3.1.1
@angular/compiler-cli: 2.4.1
like image 815
Alex Kibler Avatar asked Dec 22 '16 19:12

Alex Kibler


1 Answers

If the service is truly meant to be a singleton (one created once), don't add it to any module that will be a part of a lazy-loaded module (e.g. in the SharedModule). The reason is that lazy-loaded module get their own instances of services. If you want the service to be truly a singleton, then add it just to the AppModule, or the "Core Module" that will get imported only to the AppModule. Or you can use forRoot which will only be called in the AppModule

import { ModuleWithProviders } from '@angular/core';

@NgModule({
  declarations: [...],
  imports: [...]
})
class SharedModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: SharedModule,
      providers: [ MySingletonService ]
    }
  }
}

@NgModule({
  imports: [ SharedModule.forRoot() ]
})
class AppModule {}

@NgModule({
  imports: [ SharedModule ]
})
class OtherModule {}

Now the AppModule is the only module that imports the module with the providers.

See Also:

  • Docs on Modules. All this stuff is explained there.
like image 118
Paul Samsotha Avatar answered Oct 18 '22 00:10

Paul Samsotha