Hi for me parent routing is working fine, but for chid routes it is not redirecting and not getting errors also
in app.routing
const routes: Routes = [
{
path: 'card',
loadChildren: './cards/cards.module#CardsModule',
canActivate: [AuthGuard]
},
{
path: 'card/:id',
loadChildren: './cards/cards.module#CardsModule',
canActivate: [AuthGuard]
}]
in card-routing:
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { Cardscomponent } from './cards.component';
import { AuthGuard } from '../_services/auth.guard';
import { CardDetailsComponent } from './card-details/card-details.component';
const routes: Routes = [
{ path: '', component: Cardscomponent,
children :[
{ path: ':id', component: CardDetailsComponent}
]
}
]
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class CardsRoutingModule { }
localhost:4200/card is working
but localhost:4200/card/1234 is not working and not getting any error also, any help...
Check whether you have router-outlet in child component.
When the url updated but view not rendered, it usually comes down to missing router-outlet.
Learned that from developing a entire project with angular elements.
If you enable tracing, you can see all the router events are triggered successfully.
I need to make a angular application to work with same url for multiple routes. Example:
Route 1. Instead of navigating to:
/partner/urlparameter
Navigate to:
/partnerurlparameter
Route 2. Instead of navigating to:
/user/urlparameter
Navigate to:
/userurlparameter
Where the path is "/" followed by a dynamic value which is the parameter.
Is there a way do achieve that?
Here is how my route is configured:
{ path: '/partner/:partnerId', component: PartnerComponent },
{ path: '/customer/:customerId', component: CustomerComponent },
I want to have something like this:
{ path: '/partner/:partnerId', component: PartnerComponent },
{ path: '/:customerId', component: CustomerComponent },
Here is an example of what you want to achieve, follow the link for same.
Let me know if there are any changes.
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { RouterModule, Routes } from '#angular/router';
import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';
import { CustomerComponent } from '../customer/customer.component';
import {PartnerComponent} from '../partner/partner.component';
export const routes: Routes = [
{ path: 'partner/:partnerId', component: PartnerComponent },
{ path: ':customerId', component: CustomerComponent },
{ path: '', component: HelloComponent, pathMatch:'full' },
];
#NgModule({
imports: [BrowserModule, FormsModule, RouterModule.forRoot(routes)],
declarations: [AppComponent, HelloComponent, CustomerComponent, PartnerComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
I want to lazy load a module in the angular 2+ application.For that in 'app-routing.module' file I have following code.
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { AbcdComponent } from './abcd/abcd.component';
const routes: Routes = [
{ path: 'portfolio', loadChildren: './lazy.module#LazyModule'},
{ path: 'dashboard', loadChildren: './lazy.module#LazyModule'},
{ path: 'abcd', component:AbcdComponent}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
declarations: [
AbcdComponent
]
})
export class AppRoutingModule { }
Now, in Lazy Module I have the following code:
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { LazyParentComponent } from './lazy-parent/lazy-parent.component';
import { LazyChildComponent } from './lazy-child/lazy-child.component';
import { Routes, RouterModule } from '#angular/router';
const routes: Routes = [
{ path: 'load-me', component: DashBoardComponent },
{ path: 'load-you', component: PortfolioComponent }
];
#NgModule({
imports: [
CommonModule,
RouterModule.forChild(routes)
],
declarations: [
LazyParentComponent,
LazyChildComponent,
]
})
export class LazyModule { }
This is good enough to route https://example.com/portfolio/load-me to DashBoardComponent and https://example.com/portfolio/load-you to PortfolioComponent.
But the issue is I want to have a lazy module and for route like this https://example.com/portfolio I want to point to PortfolioComponent and https://example.com/dashboard to DashBoardComponent. Both components should be lazily loaded .Also, both components are in same module.I searched through internet but could not get any solution.Any help is appreciated.
That won't work. For each route inside of the AppRoutingModule, there needs to be its own module & and routing. So for example:
Dashboard Routes:
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { DashboardComponent } from 'some path';
export const DashboardRoutes: Routes = [
{ path: '', component: DashboardComponent }
];
#NgModule({
imports: [
RouterModule.forChild(DashboardRoutes)
],
exports: [RouterModule],
declarations: [],
providers: [],
})
export class DashboardRoutingModule { }
Dashboard Module:
#NgModule({
imports: [DashboardRoutingModule]
})
export class DashboardModule { }
App Routes:
export const routes: Routes = [
{ path: 'portfolio', loadChildren: './PathTooPortfolio#PortfolioModule'},
{ path: 'dashboard', loadChildren: './PathToDashboard#DashboardModule'},
{ path: 'abcd', component:AbcdComponent}
];
Just setup Portfolio the same way as I have Dashboard.
So I have four modules as below:
|-app.module
|-Home.module
|-private.module
|-public.module
AppModule lazy loads HomeModule and HomeModule Lazy Loads PrivateModule & PublicModule.
I have defined my routing for those modules as below:
app.routing.ts
import { NgModule} from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
const routes: Routes = [
{ path: '', loadChildren: './home/home.module#HomeModule' }
];
#NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ]
})
export class AppRoutingModule { }
Home.routing.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent } from './home/home.component';
const routes: Routes = [
{ path: '', component: HomeComponent},
{ path: 'private', loadChildren: './../private/private.module#PrivateModule'},
{ path: 'public', loadChildren: './../public/public.module#PublicModule' }
];
#NgModule({
imports: [
RouterModule.forChild(routes)
],
exports: [RouterModule]
})
export class HomeRoutingModule { }
private.routing.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { PrivateComponent } from './private/private.component';
export const privateRoutes: Routes = [
{ path: '',component:PrivateComponent}
];
#NgModule({
imports: [
RouterModule.forChild(privateRoutes)
],
exports: [RouterModule]
})
export class PrivateRoutingModule { }
public.routing.ts is same as private.routing.ts.
Now when I visit localhost:4200 it loads Home Component Correctly. but when I try to visit localhost:4200/private or localhost:4200/public it reloads the browser & only loads privateComponent.
I have used two router-outlets. one inside app.component and another in home.component.
I want to load private component inside HomeModules RouterOutlet but it loads it in AppModules RouterOutlet.
Any Inputs?
Thanks.
I think you could define private and public routes as the children of your homeModule.
Home.routing.ts
const routes: Routes = [
{
path: '',
component: HomeComponent,
children: [
{ path: 'private', loadChildren: './../private/private.module#PrivateModule'},
{ path: 'public', loadChildren: './../public/public.module#PublicModule' }
]
}
]
then your private/public route configuration will be like
const publicRoutes: Routes = [
{
path: '',
component: PublicComponent
}
]
I'm not sure which part you did wrong, that's why I was asking for an example.
But here one that works.
Good luck.
I have an Angular 2 app. The main screen (app?) looks like this...
When you click items in the top menu routerLinks, new Components load into the main view router outlet. One of those links loads up an new "Admin" Module/Component with it's own routes and new router outlet...
Then when you click the routerLinks in the left nav, new admin Components will load in the new router outlet.
But...
Angular 2 does not allow more than 1 router outlet. So clicking on any routerLink in left nav simply replaces the entire inital router outlet view.
I've seen some SO posts (older, maybe deprecated) on using "bootstrap" to load subsequent Components, but I can't get that to work. I can't even import { bootstrap } from 'anywhere at all, nothing works'. So maybe that's not the way to do this.
How can I get the Admin sub app part to work?
Thank you very, very much for sharing your Angular 2 expertise :-)
EDIT: Trying suggested solutions below. No matter where I put the routes, in the base app.routes.ts or in the sub-app admin.routes.ts, no matter how I format the routerLinks, I keep getting this error...
EDIT AGAIN: Here is the code in the routers and the template...
<!--
============================================================================
/src/app/component/admin/admin.component.html
-->
<!-- Row for entire page columnar dispaly -->
<div class="row">
<!-- Column 1: Left navigation, links to all admin components -->
<div class="col col-md-4">
<app-admin-nav></app-admin-nav>
</div>
<!-- Column 2: Rows of records, click to edit -->
<div class="col col-md-8">
<router-outlet name="admin-app"></router-outlet>
</div>
</div>
// ============================================================================
// /src/app/app.routes.ts
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { AppComponent } from './app.component';
import { GameComponent } from './component/game/game.component';
import { HomeComponent } from './component/home/home.component';
import { LoginComponent } from './component/login/login.component';
import { PlayerComponent } from './component/player/player.component';
import { AuthGuard } from './service/auth/auth.service';
import { SignupComponent } from './component/signup/signup.component';
import { EmailComponent } from './component/email/email.component';
import { AdminComponent } from './component/admin/admin.component';
// import { AdminWorldComponent } from './component/admin/world/admin-world.component';
// import { AdminModuleComponent } from './component/admin/module/admin-module.component';
// import { AdminRegionComponent } from './component/admin/region/admin-region.component';
export const router: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' }
, { path: 'home', component: HomeComponent }
, { path: 'game', component: GameComponent, canActivate: [AuthGuard] }
, { path: 'admin', component: AdminComponent, canActivate: [AuthGuard] }
// , {
// path: 'admin', component: AdminComponent, canActivate: [AuthGuard],
// children: [
// { path: 'world', component: AdminWorldComponent, outlet: 'admin-app' },
// { path: 'module', component: AdminModuleComponent, outlet: 'admin-app' },
// { path: 'region', component: AdminRegionComponent, outlet: 'admin-app' }
// ]
// },
, { path: 'login', component: LoginComponent }
, { path: 'signup', component: SignupComponent }
, { path: 'login-email', component: EmailComponent }
, { path: 'players', component: PlayerComponent, canActivate: [AuthGuard] }
];
export const routes: ModuleWithProviders = RouterModule.forRoot(router);
// ============================================================================
// /src/app/component/admin/admin.routes.ts
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { AdminComponent } from './admin.component';
import { AdminWorldComponent } from './world/admin-world.component';
import { AdminModuleComponent } from './module/admin-module.component';
import { AdminRegionComponent } from './region/admin-region.component';
export const router: Routes = [
{
path: 'admin', component: AdminComponent,
children: [
{ path: 'world', component: AdminWorldComponent, outlet: 'admin-app' }
, { path: 'module', component: AdminModuleComponent, outlet: 'admin-app' }
, { path: 'region', component: AdminRegionComponent, outlet: 'admin-app' }
]
}
];
export const routes: ModuleWithProviders = RouterModule.forRoot(router);
EDIT 3: Tried changing RouterModule.forRoot to RouterModule.forChild, sadly, same error :-/
EDIT 4: Converted routing to use 2 routing modules. Was hoping maybe that would make a difference, but same error.
New routers...
// ============================================================================
// /src/app/app-routing.module.ts
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { AppComponent } from './app.component';
import { GameComponent } from './component/game/game.component';
import { HomeComponent } from './component/home/home.component';
import { LoginComponent } from './component/login/login.component';
import { PlayerComponent } from './component/player/player.component';
import { AuthGuard } from './service/auth/auth.service';
import { SignupComponent } from './component/signup/signup.component';
import { EmailComponent } from './component/email/email.component';
import { AdminComponent } from './component/admin/admin.component';
export const appRoutes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' }
, { path: 'home', component: HomeComponent }
, { path: 'game', component: GameComponent, canActivate: [AuthGuard] }
, { path: 'admin', component: AdminComponent, canActivate: [AuthGuard] }
// , {
// path: 'admin', component: AdminComponent, canActivate: [AuthGuard],
// children: [
// { path: 'world', component: AdminWorldComponent, outlet: 'admin-app' },
// { path: 'module', component: AdminModuleComponent, outlet: 'admin-app' },
// { path: 'region', component: AdminRegionComponent, outlet: 'admin-app' }
// ]
// },
, { path: 'login', component: LoginComponent }
, { path: 'signup', component: SignupComponent }
, { path: 'login-email', component: EmailComponent }
, { path: 'players', component: PlayerComponent, canActivate: [AuthGuard] }
];
#NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
exports: [
RouterModule
]
})
export class AppRoutingModule { }
// ============================================================================
// /src/app/admin/admin-routing.module.ts
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { AdminComponent } from './admin.component';
import { AdminWorldComponent } from './world/admin-world.component';
import { AdminModuleComponent } from './module/admin-module.component';
import { AdminRegionComponent } from './region/admin-region.component';
export const adminRoutes: Routes = [
{
path: 'admin', component: AdminComponent,
children: [
{ path: 'world', component: AdminWorldComponent, outlet: 'admin-app' }
, { path: 'module', component: AdminModuleComponent, outlet: 'admin-app' }
, { path: 'region', component: AdminRegionComponent, outlet: 'admin-app' }
]
}
];
#NgModule({
imports: [
RouterModule.forChild(adminRoutes)
],
exports: [
RouterModule
]
})
export class AdminRoutingModule { }
EDIT 5: IT'S WORKING!
Removed the routing modules, returned to exporting routes config per Tyler's suggestion. He is right, the routing modules do not work. Tyler worked with me a lot so I'm accepting his answer. Thank you Tyler for your help!
Here is how you can setup a parent app with it's own router-outlet, then on the parent click a link to load up a child app with it's own new router-outlet. The child app loads/replaces the parent app router-outlet.
There is really nothing special in the parent app module or routes. They're just how I had them before this post.
The important points to note, at least in my case today, do not use a name="" attrib in the child router-outlet. This will cause "Error: Cannot match any routes...". Do not use routing modules like I tried above, this also causes "Error: Cannot match any routes...". Do not use outlet: 'blah' in the routes, this also causes "Error: Cannot match any routes...". Make sure you set up the child route config children: [] exactly as you see below in admin.routes.ts. Also, note the RouterModule.forChild(router) in the child routes. These things fixed the issue for me today.
PARENT APP
// ============================================================================
// src/app/app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { AngularFireModule } from 'angularfire2';
import { firebaseConfig } from '../environments/firebase.config';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
// import { AppRoutingModule } from './app-routing.module';
import { routes } from './app.routes';
// Components
import { AppComponent } from './app.component';
import { HomeComponent } from './component/home/home.component';
import { GameComponent } from './component/game/game.component';
import { PlayerComponent } from './component/player/player.component';
import { LoginComponent } from './component/login/login.component';
import { SignupComponent } from './component/signup/signup.component';
import { EmailComponent } from './component/email/email.component';
// Admin Module
import { AdminModule } from './component/admin/admin.module';
// Services
import { AuthGuard } from './service/auth/auth.service';
import { AuthPlayerService } from './service/auth/auth-player.service';
import { MdbService } from './service/mongo/mdb.service';
import { PlayerMdbService } from './service/mongo/player-mdb.service';
#NgModule({
declarations: [
AppComponent
, HomeComponent
, GameComponent
, PlayerComponent
, LoginComponent
, SignupComponent
, EmailComponent
],
imports: [
BrowserModule
, FormsModule
, HttpModule
, AdminModule
, AngularFireModule.initializeApp(firebaseConfig)
, NgbModule.forRoot()
// , AppRoutingModule
, routes
],
providers: [
AuthGuard
, AuthPlayerService
, MdbService
, PlayerMdbService
],
bootstrap: [AppComponent]
})
export class AppModule { }
// ============================================================================
// /src/app/app.routes.ts
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { AppComponent } from './app.component';
import { GameComponent } from './component/game/game.component';
import { HomeComponent } from './component/home/home.component';
import { LoginComponent } from './component/login/login.component';
import { PlayerComponent } from './component/player/player.component';
import { AuthGuard } from './service/auth/auth.service';
import { SignupComponent } from './component/signup/signup.component';
import { EmailComponent } from './component/email/email.component';
import { AdminComponent } from './component/admin/admin.component';
export const router: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'game', component: GameComponent, canActivate: [AuthGuard] },
{ path: 'admin', component: AdminComponent, canActivate: [AuthGuard] },
{ path: 'login', component: LoginComponent },
{ path: 'signup', component: SignupComponent },
{ path: 'login-email', component: EmailComponent },
{ path: 'players', component: PlayerComponent, canActivate: [AuthGuard] }
];
export const routes: ModuleWithProviders = RouterModule.forRoot(router);
CHILD APP
// ============================================================================
// /src/app/admin/admin.module.ts
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { CommonModule } from '#angular/common';
import { routes } from './admin.routes';
// import { AdminRoutingModule } from './admin-routing.module';
import { AdminComponent } from './admin.component';
import { AdminRecsComponent } from './admin-recs.component';
import { AdminFormComponent } from './admin-form.component';
import { AdminNavComponent } from './admin-nav.component';
import { AdminWorldComponent } from './world/admin-world.component';
import { AdminModuleComponent } from './module/admin-module.component';
import { AdminRegionComponent } from './region/admin-region.component';
#NgModule({
imports: [
CommonModule
, FormsModule
// , AdminRoutingModule
, routes
]
, declarations: [
AdminComponent
, AdminNavComponent
, AdminRecsComponent
, AdminFormComponent
, AdminWorldComponent
, AdminModuleComponent
, AdminRegionComponent
]
, schemas: [CUSTOM_ELEMENTS_SCHEMA]
, exports: [
AdminRecsComponent
, AdminFormComponent
, AdminNavComponent
// , AdminWorldComponent
// , AdminModuleComponent
// , AdminRegionComponent
]
// , bootstrap: [AdminComponent]
})
export class AdminModule { }
// ============================================================================
// /scr/app/admin/admin.routes.ts
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { AdminComponent } from './admin.component';
import { AdminWorldComponent } from './world/admin-world.component';
import { AdminModuleComponent } from './module/admin-module.component';
import { AdminRegionComponent } from './region/admin-region.component';
export const router: Routes = [
{
path: 'admin', component: AdminComponent,
children: [
{ path: 'world', component: AdminWorldComponent },
{ path: 'module', component: AdminModuleComponent },
{ path: 'region', component: AdminRegionComponent },
]
}
];
export const routes: ModuleWithProviders = RouterModule.forChild(router);
Not sure where you heard that Angular2 does not allow more than 1 router-outlet. I am using several in a large application.
Your main app.component will have a router-outlet to handle the root routes. If one of your routes lazy-loads the Admin Module, that admin module will have it's root component that contains the side menu bar and a router-outlet for all the children routes.
Example:
//app.routes
export const ROUTES: Routes = [
// Main redirect
{ path: '', component: MainViewComponent },
{
path: 'admin',
loadChildren: './admin/admin.module#AdminModule'
}
]
Your MainViewComponent can contain the top navbar and a router-outlet.
Then the Admin router config may look like this:
export const routes: Routes = [
{
path: '',
component: AdminComponent,
children: [
{ path: '', component: Component1},
{ path: 'component2', component: Component2}
]
}
];
Your root component in the Admin module may contain the side bar menu and a router-outlet to show the children components.
You can also do named router-outlets. An example of this is having two router-outlets side-by-side:
<router-outlet></router-outlet>
<router-outlet name="popup"></router-outlet>
Your router config would look like this:
{
path: 'compose',
component: ComposeMessageComponent,
outlet: 'popup'
},
And you would use it like this:
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
Or clear the content with this:
this.router.navigate([{ outlets: { popup: null }}]);
See the docs or this article for more details.
Hope that helps.
Edit
When using the route config for a lazily loaded child, make sure your route configs are loaded properly in your modules. The root route config will be loaded in the root AppModule with RouterModule.forRoot(routes) and the child routes are in the Child module with RouterModule.forChild(routes).
Your route config and modules need to look like this(don't create a separate module just to hold routing config):
//Admin Routes
export const adminRoutes: Routes = [
{
path: 'admin', component: AdminComponent,
children: [
{ path: 'world', component: AdminWorldComponent, outlet: 'admin-app' }
, { path: 'module', component: AdminModuleComponent, outlet: 'admin-app' }
, { path: 'region', component: AdminRegionComponent, outlet: 'admin-app' }
]
}
];
//Admin Module:
import { adminRoutes } from './admin.routes';
#NgModule({
imports: [
...
RouterModule.forChild(adminRoutes),
]
...
//App Routes(lazy load Admin module)
export const appRoutes: Routes = [
{ path: 'admin', loadChildren: './admin/admin.module#AdminModule' },
....
//App Module
import { appRoutes } from './app.routes';
#NgModule({
imports: [
...
RouterModule.forRoot(appRoutes),
]
...
Hope that helps.
Yes, there is a way to do this.
You need to name your router outlet like:
<router-outlet name="child1"></router-outlet>
<router-outlet name="child2"></router-outlet>
And inside your router you need to define what router-outlet should route use:
{
path: 'home', // you can keep it empty if you do not want /home
component: 'appComponent',
children: [
{
path: '',
component: childOneComponent,
outlet: 'child1'
},
{
path: '',
component: childTwoComponent,
outlet: 'child2'
}
]
}
Original post:
Angular2 multiple router-outlet in the same template