Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type X is part of the declarations of 2 modules (Angular 2 RC5)

Tags:

angular

I'm toying around with Angular 2 RC5 and have run into the following problem:

"Error: Type WelcomeComponent is part of the declarations of 2 modules: WelcomeModule and AppModule!

app.module.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { Routes, RouterModule }  from '@angular/router';
import { WelcomeModule } from './welcome/welcome.module';
import { AppComponent }  from './app.component';
import { 
    routing, 
    appRoutingProviders 
} from './app.routing';

@NgModule({
  imports:      [ 
  BrowserModule, 
  RouterModule, 
  WelcomeModule,
  routing
  ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ],
  providers:    [ appRoutingProviders ]
})
export class AppModule { }

app.routing.ts

import { 
    Routes,
    RouterModule 
} from '@angular/router';

import { welcomeRoutes } from './welcome/welcome.routing';

const appRoutes: Routes = [
     ...welcomeRoutes
];

export const appRoutingProviders: any[] = [];
export const routing = RouterModule.forRoot(appRoutes);

welcome.module.ts

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

import { WelcomeComponent } from './welcome.component';

@NgModule({
    declarations: [ WelcomeComponent ]
})
export class WelcomeModule { }

welcome.routing.ts

import { 
    Routes,
    RouterModule 
} from '@angular/router';

import { WelcomeComponent } from './welcome.component';

export const welcomeRoutes: Routes = [
    { path: 'welcome', component: WelcomeComponent }
];

export const welcomeRoutingProviders: any[] = [];
export const welcomeRouting = RouterModule.forChild(welcomeRoutes);

I can see what Angular is complaining about, welcomeRoutes requires WelcomeComponent from WelcomeModule to be defined, appRoutes references welcomeRoutes and routing is imported in AppModule which has WelcomeModuleimported, but how am I supposed to build a routes graph spanning multiple modules then?

The only solution that I can see is to remove

import { WelcomeModule } from './welcome/welcome.module'

but that kind of would defy the whole purpose of having modules in the first place, wouldn't it?

like image 502
Thorsten Westheider Avatar asked Aug 16 '16 03:08

Thorsten Westheider


3 Answers

This problem was simply fixed for me by moving the declaration to a commonly used module and including it in the export so it could be used from other modules. Simplified code example below.

@NgModule({
    imports: [CommonModule],
    declarations: [
        WelcomeComponent
    ],
    exports: [
        WelcomeComponent
    ],
    providers: [
    ]
})
like image 66
My Stack Overfloweth Avatar answered Nov 15 '22 17:11

My Stack Overfloweth


You load the same route configuration for root and child but they have to be different route configurations. For a full example see https://angular.io/docs/ts/latest/guide/router.html

like image 31
Günter Zöchbauer Avatar answered Nov 15 '22 17:11

Günter Zöchbauer


Well, the first time I added WelcomeComponent to AppModule was by writing

import { WelcomeModule } from './welcome/welcome.module';

because WelcomeComponent is inside declarations of that module.

I then added WelcomeComponent a second time by writing

const appRoutes: Routes = [
     ...welcomeRoutes
];

as WelcomeComponent is the component to navigate to and it appears it is added to AppModule implicitly.

I solved the problem by changing app.routing.ts to

import { 
    Routes,
    RouterModule 
} from '@angular/router';

const appRoutes: Routes = [
    { path: '', redirectTo: '/welcome', pathMatch: 'full' }
];

export const appRoutingProviders: any[] = [];
export const routing = RouterModule.forRoot(appRoutes);

Declaring welcomeRouting as RouterModule.forChild makes welcome a child route automatically.

like image 2
Thorsten Westheider Avatar answered Nov 15 '22 15:11

Thorsten Westheider