3

I'm trying to configure my application to make use of Lazy Loaded Modules in RC5. This is the problem i'm running in to.

I have a module that uses RouterModule.forChild(router) and gets lazy loaded lets call it LevelOneModule. This module also has a few modules that get lazy loaded lets call them LevelTwoModule-s. This works for the most part but i have to mayor problems:

  1. I provide a service in my LevelOneModule that i need to have as a singleton in LevelTwoModule-s but for some reason each LevelTwoModule has its own instance of the service.

Here is an example of the code:

LevelOneModule

@NgModule({
    imports: [
        SharedModule,
        levelOneRouter
    ],
    providers: [SomeService],
    declarations: [...]
})

LevelTwoModule:

@NgModule({
    imports: [
        SharedModule,
        levelTwoRouter
    ],
    providers: [],
    declarations: [...]
})
  1. I want the LevelOneModule to register some declarations which i need available in multiple LevelTwoModule-s and i'm not quit sure how to achieve this.

If i just try to register the declarations in the LevelOneModule:

declarations: [SomeComponent, ANotherComponent]

I get the unrecognized element error, and if i try to register the declaration in each LevelTwoModule separately i get the is part of the declarations of 2 modules error.

I've also tried to make another SharedModule just for the LevelOneModule and that didn't work also.

Any help or info is greatly appreciated, just something to point me in the right direction.

1 Answer 1

2

Answer to question #1

You should ask LevelOneModule to register the singleton, you can do this by putting the required providers in a static method:

@NgModule({
    imports: [
        SharedModule,
        levelOneRouter
    ],
    providers: [],
    declarations: []
})
export class LevelOneModule{
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: LevelOneModule,
      providers: [SomeService]
    };
  }
}

After that, call in your LevelTwoModule this static method when importing:

@NgModule({
    imports: [
        LevelOneModule.forRoot(),
        levelTwoRouter
    ],
    providers: [],
    declarations: []
})

This way, the providers instantiated within LevelOneModule gets passed on as a singleton to the child module.

For further info: guide

Answer to question #2

To make declarations (pipes/components/directives/services) available in another module. You should add these declarations to the exports parameter:

@NgModule({
    imports: [
        SharedModule,
        levelOneRouter
    ],
    providers: [],
    declarations: [
        ComponentIJustWantToUseInHere,
        ComponentIWantToUseHereAndElsewhere
    ],
    exports : [
        ComponentIWantToUseHereAndElsewhere,
        ComponentOrPipeOrWhateverIWantToUseElsewhere
    ]
})
export class LevelOneModule{
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: LevelOneModule,
      providers: [SomeService]
    };
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Oh god you're right, and it's so simple, not sure how I missed that. Do you maybe have a solution for the second problem as well?
In regards to the first part. I can't get it to work. They are still singletons should i maybe import the LevelOneModule.forRoot() in the app.module.ts as well? But i'm afraid that beats the point of lazy loading.
The export option also doesn't work. I think i'm going to have to make a plunker to demonstrake this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.