0

I was going through the Angular Tour Of Heroes tutorial and I just got to the router section. I was confused as to why they do this:

app-routing.module.ts file:

@NgModule({
    //Exporting the routermodule allows router directives available to AppModule components
    //This initialized the routermodule with routes so available through
    exports : [RouterModule],
    imports : [RouterModule.forRoot(routes)]
})

What does the export really do? I noticed that had I not created this module and done this all in "app.module.ts" file, all I would need to do is add RouterModule.forRoot(routes) to the import. I don't even need to import RouterModule.

What I don't understand is if the app.module.ts is going to import app-routing.module.ts file which will import RouterModule.forRoot(routes), why does the module still need to export RouterModule? Shouldn't RouterModule.forRoot(routes) provide the directives?

Sorry this may be confusing but I just couldn't understand the significance of the export.

2 Answers 2

5

There is a lot going on here and I agree it can be a challenge to wrap your mind around. The imports array is how you register dependencies with a module and the exports array is how you declare those dependencies as public making their services, directives, components, etc available for use in other modules.

Since you mentioned RouterModule I will use that as an example. app.module.ts is the root of your application and any module registered at the root will be made available to the entire application. Most applications require routing and therefore your application requires the RouterModule. To keep the code clean in your root module a common pattern is to consolidate your routing logic into an app-routing-module.ts.

In order to use all the routing services/directives Angular provides, you had to import RouterModule into app-routing.module.ts. By importing RouterModule you were able to use it's directives to define your routes in app-routing.module.ts. Now you only want one instance of the router service in your application. To accomplish that you called the forRoot() method when importing RouterModule. The forRoot() method is a convention established by Angular to create singletons, in this case it created a singleton of the router service (this is a whole different subject to look into later).

Keep in mind you want to import app-routing.module.ts in your root module (app.module.ts) to register your routes at the root of your application. In addition to that, you still want to be able to use routing in the rest of your application to navigate around. To accomplish this you then declared RouterModule as an export in app-routing.module.ts thereby making all it's directives and services available for use by the rest of you application when you registered app-routing.module.ts in the root of your application (app.moudle.ts)

This is a complex subject and there are a lot of good articles on the matter. To get a more detailed explanation I would recommend starting with this article:

In depth article on modules

Sign up to request clarification or add additional context in comments.

4 Comments

Why can't I just export RouterModule.forRoot(routes) (since this is a module as well) then?
the forRoot() method only returns a provider, the router service. If you only exported RouterModule.forRoot() it wouldn't make much sense., because you wouldn't be able to use the rest of the providers and directives that RouterModule has to make routing possible in the rest of your application.
Mmm I I think I get it. In the example, we wanted to use the router-outlet component and that is in the RouterModule. By exporting it, all directives, components etc are available to whoever imports it and allowed me to use that component in the app.component. I think I get it but the convention is really weird and a little confusing.
I am happy it is starting to make sense, I am glad I could help. It definitely is a lot to understand. To get a really good understanding it helps to learn more about Angulars compilation process and it's use of injectors and how it applies to modules, providers, and components. If my answer helped would you please mark it.
0

app.module.ts

import { FooModule } from 'foo.module';
@NgModule({
…
    declarations: [ AppComponent, OtherComponent ],
    imports: [ ReactiveFormsModule ],
    exports: [],
…

foo.module.ts

@NgModule({
…
    declarations: [ SomeComponent ],
    imports: [ SomeModule ],
    exports: [ SomeDirective ],
…

This means that in foo.module, SomeModule can only be used by SomeComponent. Whereas SomeDirective can be used by SomeComponent and by the components that are declared, in any NgModule, that imports foo.module.

So, because app.module, imports foo.module, then both SomeComponent & OtherComponent [as well as AppComponent] can use SomeDirective.

This is why you never see the app.module, using the exports property. Because it is at the top of the module tree, it cannot be imported into another NgModule. This means that if it ever had members, in its exports array, they would never be exposed.

Comments

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.