Function module, non-exporting component

My simple application has a root module called AppModule and a function module called HomeModule. I am trying to create a route for a component called HomeComponent (which is part of the HomeModule), but all I get is

Module "HomeModule" has no exported member 'HomeComponent' 

app.routing.ts

 import { Routes, RouterModule } from '@angular/router' import { HomeComponent } from './Home/home.module.ts' // HomeComponent not found const appRoutes: Routes = [ { path: '', component: HomeComponent } ]; export const appRoutingProviders: any[] = [ ]; export const routing = RouterModule.forRoot(appRoutes); 

home.module.ts

 import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HomeComponent } from './home.component.ts'; @NgModule({ imports: [ BrowserModule ], declarations: [ HomeComponent ], exports: [ HomeComponent ] }) export class HomeModule { } 

home.component.ts

 import { Component } from '@angular/core'; @Component({ selector: 'home', template: '<h1>Hello World</h1>' }) export class HomeComponent { } 

Why doesn't HomeModule export its component?

+7
import module angular typescript
source share
4 answers

Ref1: http://angularjs.blogspot.com/2016/08/angular-2-rc5-ngmodules-lazy-loading.html Ref2: https://angular.io/docs/ts/latest/guide/ngmodule.html #! # imports

Problem 1: Import / Export NgModel

 import { HomeComponent } from './Home/home.module.ts' // HomeComponent not found 

home.module.ts exports a HomeModule , not a HomeComponent .

Exporting @NgModule creates the Angular2 functions of these export components available for the import module. functions can be template directives, selector, injection service, etc.

The function of the home component is its selector. Therefore, importing HomeModule into app.module will make the HomeComponent home selector available to any app.module component.

In order for HomeModule to export HomeComponent explicitly, index.js and index.d.ts are needed. (Inspired by Fabio Antune's answer)

Use home selector

To use this, exports: [ HomeComponent ] is required in home.module.ts.

app.module.ts

 import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; import { HomeModule } from './Home/home.module'; import { routing } from './app.routing'; @NgModule({ imports: [ BrowserModule, HomeModule, routing], declarations: [ AppComponent], bootstrap: [AppComponent] }) export class AppModule { } 

app.component.ts using the home selector

 import {Component} from '@angular/core'; @Component({ selector: 'app-component', template: ` <h1>{{title}}</h1> <home></home>` }) export class AppComponent { title = 'APP'; } 

Use HomeComponent

To use HomeComponent directly, we need to add index.js and index.d.ts to. / Home

./Home/index.js

 exports.HomeModule = require('./home.module').HomeModule; exports.HomeComponent = require('./home.component').HomeComponent; 

./Home/index.d.ts

 exports * './home.module'; exports * from './home.component'; 

Then import the Home Module, e.g. npm package

app.routing.ts

 // We are importing the module directory, not ./Home/home.module.ts import { HomeComponent } from './Home'; import { Routes, RouterModule } from '@angular/router' const appRoutes: Routes = [ { path: '', component: HomeComponent } ]; export const appRoutingProviders: any[] = [ ]; export const routing = RouterModule.forRoot(appRoutes); 

Problem 2: Routing (for the child module)

To go to the module, the child module must have its own router settings.

Use loadChildren in parent routing (app.routing.ts).

Use RouterModule.forChild in child routing (home.routing.ts).

app.module.ts

 import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; import { HomeModule } from './Home/home.module'; import { routing } from './app.routing'; @NgModule({ imports: [ BrowserModule, HomeModule, routing], declarations: [ AppComponent], bootstrap: [AppComponent] }) export class AppModule { } 

app.component.ts

 import {Component} from '@angular/core'; @Component({ selector: 'app-component', template: ` <h1>{{title}}</h1> <nav> <a routerLink="/home" routerLinkActive="active">Home</a> </nav> <router-outlet></router-outlet>` }) export class AppComponent { title = 'APP'; } 

app.routing.ts

 import { Routes, RouterModule } from '@angular/router'; const appRoutes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, { path: 'home', loadChildren: './Home/home.module' } ]; export const appRoutingProviders: any[] = [ ]; export const routing = RouterModule.forRoot(appRoutes); 

Home /home.module.ts

 import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HomeComponent } from './home.component'; import { routing } from './home.routing'; @NgModule({ imports: [ BrowserModule, routing], declarations: [ HomeComponent] }) export class HomeModule { } 

Home /home.routing.ts

 import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './home.component'; const homeRoutes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, { path: 'home', component: HomeComponent } ]; export const appRoutingProviders: any[] = [ ]; export const routing = RouterModule.forChild(homeRoutes); 
+9
source share

Function modules should import CommonModule instead of BrowserModule

+3
source share

When setting up a route where your app.route.ts will load your HomeModule using loadChildren , you have to do two things. Or:

 export default class HomeModule() {} // note *default* 

or in app.route.ts you need to add #HomeModule :

 import { Routes, RouterModule } from '@angular/router'; const appRoutes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, { path: 'home', loadChildren: './Home/home.module#HomeModule' <-- or like this } ]; export const appRoutingProviders: any[] = [ ]; export const routing = RouterModule.forRoot(appRoutes); 

If you plan on adding additional routes to home.route.ts, it might be a good idea to define a children property, for example:

 import { Routes, RouterModule } from '@angular/router'; const homeRoutes: Routes = [ path: "", component: HomeComponent, children: [ { path: "", component: HomeComponent }, { path: ":id", component: HomeDetailsComponent" } ] ] 

What you should remember in the above case is that your main RouterOutlet in your app.component.ts (if it is called that way) will not serve a route like http://some_url/Home/1 to load HomeDetailsComponent.

The fact is that the route served by HomeDetailsComponent is a child route of HomeComponent , and as such HomeComponent template or templateUrl must have its own <router-outlet></router-outlet> defined, otherwise you will receive a Cannot find primary outlet to load 'HomeDetailsComponent'. error message Cannot find primary outlet to load 'HomeDetailsComponent'.

+1
source share

@yourfriendzak, just remove the '.ts' from the instructions below:

 import { HomeComponent } from './Home/home.module.ts' // HomeComponent not found 

Hope this helps ...

+1
source share

All Articles