how can I make sure to have at least 2 router-outlets and manage them at the routing level?
can link me a working jsfillde or stackblitz or similar?
edited re open problem
APP COMPONENT HTML
<main [#fadeInAnimation]="o.isActivated ? o.activatedRoute : ''">
<router-outlet #o="outlet" name="main"></router-outlet>
<router-outlet #o="outlet" name="second"></router-outlet>
</main>
APP MODULE
import { BrowserModule } from '#angular/platform-browser';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { HttpClientModule } from '#angular/common/http';
import { NgModule, APP_INITIALIZER } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
// components
import { AppComponent } from './app.component';
import { HomeComponent } from './components/home/home.component';
// models
import { Permissions } from '../app/models/permissions';
// guards
import { CanAccess } from '../app/guards/canaccess';
import { OtherComponent } from './components/other/other.component';
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';
const permissions: Permissions = new Permissions();
const appRoute: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent, data: { permission: permissions }, canActivate: [CanAccess], outlet: 'main' },
{ path: 'other', component: OtherComponent, data: { permission: permissions }, canActivate: [CanAccess], outlet: 'second' },
{ path: 'pageNotFound', component: PageNotFoundComponent, data: { permission: permissions }, canActivate: [CanAccess], outlet: 'main' },
{ path: '**', redirectTo: 'pageNotFound', pathMatch: 'full' },
];
export function appConfigFactory() {
try {
return () => true;
} catch (e) {
console.log(`catch load: ${e}`);
}
}
#NgModule({
declarations: [
AppComponent,
HomeComponent,
OtherComponent,
PageNotFoundComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
RouterModule.forRoot(appRoute)
],
providers: [
CanAccess,
{
provide: APP_INITIALIZER,
useFactory: appConfigFactory,
deps: [],
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
ERROR
ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'home'
Error: Cannot match any routes. URL Segment: 'home'
can view on editor
https://stackblitz.com/edit/angular-ghusfs
thanks
You may define parent child component to use multiple router-outlets like this.
{
path: 'shop', component: ParentShopComponent,
children : [{
path: 'hello', component: ChildShopComponent
}]
}
Your first <router-outlet> will be in app component & second in ParentShopComponent rest of components can lend in child level or parent.
But if your relationship is child parent than check this out Named Router Outlets
Example
This is main Router OUtlet
These are named ones
<div class="columns">
<md-card>
<router-outlet name="list"></router-outlet>
</md-card>
<md-card>
<router-outlet name="bio"></router-outlet>
</md-card>
</div>
And here's how you use them
{ path: 'speakersList', component: SpeakersListComponent, outlet: 'list' }
Related
There are some similar discussions, but the solutions did not work. I've attempted to recreate the module a couple of times now and Angular still throws the error Maximum call stack size exceeded. The admin component is brand new as well. All of these have been generated using CLI.
Here's my code:
App Routing
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { AuthGuard } from './guards/auth/auth.guard';
const routes: Routes = [
{
path: 'dashboard',
pathMatch: 'full',
data: { authorized: [true] },
canActivate: [AuthGuard],
loadChildren: () =>
import('./modules/feature/dashboard/dashboard.module').then(
(m) => m.DashboardModule
),
},
///// this admin import is the issue and I know this because if I comment it out then the app works
///// fine...
{
path: 'admin',
pathMatch: 'full',
data: { authorized: [true] },
canActivate: [AuthGuard],
loadChildren: () =>
import('./modules/feature/admin/admin.module').then((m) => m.AdminModule),
},
{
path: '',
pathMatch: 'full',
data: { authorized: [false] },
loadChildren: () =>
import('./modules/feature/website/website.module').then(
(m) => m.WebsiteModule
),
},
// {
// path: '*',
// component: MainComponent,
// data: { authorized: [false] },
// },
];
#NgModule({
imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' })],
exports: [RouterModule],
})
export class AppRoutingModule {}
Module
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { AdminRoutingModule } from 'src/app/routing/feature/admin-routing/admin-routing.module';
import { AdminComponent } from 'src/app/components/feature/admin/admin.component';
import { AdminService } from 'src/app/services/feature/admin.service';
#NgModule({
declarations: [AdminComponent],
imports: [CommonModule, AdminRoutingModule],
providers: [AdminService],
})
export class AdminModule {}
Admin Routing
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { AdminComponent } from 'src/app/components/feature/admin/admin.component';
const routes: Routes = [
{
path: '',
component: AdminComponent,
children: [],
},
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class AdminRoutingModule {}
Sometimes you bang your head against the wall because you've looked over your code a hundred times. Knowing good and well that it's not an error on your end. To find that the error can be solved via something simple. Like stopping the server, closing visual studio....re-opening visual studio and re-booting the server.
Which btw, solved my issue.
I tried to create a 404 page on my Web Application, so I create the component and add the routes to the app-rouging.module.ts but the website is always redirected to the 404 page even if I enter "/home" in the URL.
The not-found component is in the public module, attached to a not-found module :
import { NgModule } from '#angular/core';
import { SharedModule } from 'src/app/shared/shared.module';
import { NotFoundComponent } from './not-found/not-found.component';
#NgModule({
declarations: [NotFoundComponent],
imports: [
SharedModule
]
})
export class NotFoundModule { }
public.module.ts :
import { NgModule } from '#angular/core';
import { PublicRoutingModule } from './public-routing.module';
import { SharedModule } from '../shared/shared.module';
import { MainPageComponent } from './main-page/main-page.component';
import { CookieInformationComponent } from './cookie-information/cookie-information.component';
import { LegaleInformationComponent } from './legale-information/legale-information.component';
import { MapComponent } from './map/map.component';
import { AgmCoreModule } from '#agm/core';
import { InnerHTMLComponent } from './inner-html/inner-html.component';
import { NotFoundModule } from './not-found/not-found.module';
#NgModule({
declarations: [MainPageComponent, CookieInformationComponent, LegaleInformationComponent, MapComponent, InnerHTMLComponent],
imports: [
SharedModule,
PublicRoutingModule,
AgmCoreModule,
NotFoundModule
]
})
export class PublicModule { }
I have 3 files for routing : app-routing, private-routing and public-routing :
app-routing.module.ts :
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { NotFoundComponent } from './public/not-found/not-found/not-found.component';
const APP_ROUTES: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: '**', component: NotFoundComponent }
];
#NgModule({
imports: [RouterModule.forRoot(APP_ROUTES)],
exports: [RouterModule]
})
export class AppRoutingModule { }
public-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { MainPageComponent } from '../public/main-page/main-page.component'
import { LegaleInformationComponent } from './legale-information/legale-information.component';
import { CookieInformationComponent } from './cookie-information/cookie-information.component';
const APP_ROUTES_PUBLIC: Routes = [
{ path: 'home', component: MainPageComponent },
{ path: 'legal', component: LegaleInformationComponent },
{ path: 'cookie', component: CookieInformationComponent }
];
#NgModule({
imports: [RouterModule.forChild(APP_ROUTES_PUBLIC)],
exports: [RouterModule]
})
export class PublicRoutingModule { }
private-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { AdminComponent } from './admin/admin/admin.component';
import { UploadFileComponent } from './admin/upload-file/upload-file.component';
import { QRCreateComponent } from './admin/qr-code-management/create/create.component';
import { QRUpdateComponent } from './admin/qr-code-management/update/update.component';
const APP_ROUTES_PRIVATE: Routes = [
{ path: 'admin', component: AdminComponent },
{ path: 'admin/upload-file', component: UploadFileComponent },
{ path: 'admin/qr-code-management/create', component: QRCreateComponent },
{ path: 'admin/qr-code-management/update', component: QRUpdateComponent }
];
#NgModule({
imports: [RouterModule.forChild(APP_ROUTES_PRIVATE)],
exports: [RouterModule]
})
export class PrivateRoutingModule {
Look at your app routing module declaration:
const APP_ROUTES: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: '**', component: NotFoundComponent }
];
If someone goes to, for example 'http://localhost:3000/', you redirect him to 'http://localhost:3000/home'. But you don't have route declaration for 'home' path, so router will display NotFoundComponent.
You need to add declaration for 'home' path. For example:
const APP_ROUTES: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home',
loadChildren: () => import('./public.module').then(m => m.PublicModule) },
{ path: '**', component: NotFoundComponent }
];
Note 1: you need to have route with path: '' in PublicModule to make it work. Probably you have to change path 'home' to simple empty path.
Note 2: I'm assuming you want to lazy load your modules. You can read more about it: https://angular.io/guide/lazy-loading-ngmodules
So basically I am trying to create a lazy loaded feature module in my application I have been following the official angular docs - but for some reason its not working.
I have set up my feature module DashboardModule as shown below
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
// MODULES
import { DashboardRoutingModule } from './dashboard-routing.module';
// COMPONENTS
import { DashboardComponent } from './dashboard/dashboard.component';
import { DashboardAlertComponent } from './dashboard-alert/dashboard-alert.component';
import { DashboardSummaryComponent } from './dashboard-summary/dashboard-summary.component';
import { DashboardTasksComponent } from './dashboard-tasks/dashboard-tasks.component';
import { HoldingPageComponent } from './holding-page/holding-page.component';
#NgModule({
imports: [CommonModule, DashboardRoutingModule],
declarations: [
DashboardComponent,
DashboardAlertComponent,
DashboardSummaryComponent,
DashboardTasksComponent,
HoldingPageComponent,
]
})
export class DashboardModule {}
then in my DashboardRoutingModule
import { NgModule } from '#angular/core';
import { RouterModule } from '#angular/router';
import { ActivityComponent } from '../activity-components/activity/activity.component';
import { IsLockedRouteGuard } from '#app/shared/common/auth/is-locked-route-guard';
import { DashboardSummaryComponent } from './dashboard-summary/dashboard-summary.component';
import { SyncComponent } from '#app/popup-components/sync/sync.component';
import { DashboardAlertComponent } from './dashboard-alert/dashboard-alert.component';
import { ChartContainerComponent } from '../chart-components/chart-container/chart-container.component';
import { DashboardTasksComponent } from './dashboard-tasks/dashboard-tasks.component';
#NgModule({
imports: [
RouterModule.forChild([
{ path: 'activity', component: ActivityComponent, canActivate: [IsLockedRouteGuard] },
{ path: 'snapshot', component: DashboardSummaryComponent },
{ path: 'sync', component: SyncComponent },
{
path: 'alerts',
component: DashboardAlertComponent,
canActivate: [IsLockedRouteGuard]
},
{ path: 'charts', component: ChartContainerComponent, canActivate: [IsLockedRouteGuard] },
{ path: 'tasks/:sort', component: DashboardTasksComponent, canActivate: [IsLockedRouteGuard] },
])
],
exports: [RouterModule]
})
export class DashboardRoutingModule {}
so as per the angular docs this has been set up correctly..
now in my AppRoutingModule
import { NgModule } from '#angular/core';
import { RouterModule } from '#angular/router';
import { AppComponent } from './app.component';
import { AppRouteGuard } from './shared/common/auth/auth-route-guard';
#NgModule({
imports: [
RouterModule.forChild([
{
path: 'app',
component: AppComponent,
children: [
{
path: '',
children: [{ path: '', redirectTo: '/dashboard/alerts', pathMatch: 'full' }]
},
{
path: 'main',
canActivate: [AppRouteGuard],
loadChildren: () => import('./main/main.module').then(m => m.MainModule),
data: { preload: true }
},
{
path: 'dashboard',
loadChildren: () => import('./main/dashboard/dashboard.module').then(m => m.DashboardModule)
},
]
}
])
],
exports: [RouterModule]
})
export class AppRoutingModule {}
but whats happening is when I try and go to /dashboard.. I get this error
Component HoldingPageComponent is not part of any NgModule or the module has not been imported into your module.
but I am clearly importing it in the DashboardModule as shown above.. what am I doing wrong??
Thanks
i don't see
RouterModule.forRoot
i think you should use it in AppRoutingModule instead of
RouterModule.forChild
I'm facing a common problem in a backend app.
I got several ressources which can be viewed by consulting this kind of routes:
reports/view/:id
campains/view/:id
suts/view/:id
certifications/view/:id
Note that the route ends with the same part : /view/:id.
My app modules are :
App.module
|-MainLayoutModule
|- ReportModule
|- CampaignModule
|- SutModule
|- ...
Each module (except mainlayoutModule) defines it's own routing.
App.routing
{
path:'certification',
loadChildren: './+certification/certification.module#CertificationModule',
canActivate:[AuthGuard]
},
{
path:'reports',
loadChildren: './+report/report.module#ReportModule'
canActivate:[AuthGuard],
},
{
path:'suts',
loadChildren: './+sut/sut.module#SutModule',
canActivate:[AuthGuard]
},
{
path:'campaigns',
loadChildren: './+campaign/campaign.module#CampaignModule',
canActivate:[AuthGuard]
},...
Report.routing
import { Routes, RouterModule } from '#angular/router';
import { ReportDetailsComponent } from "./ReportDetails/report-details.component";
import { ReportDetailsResolver } from "./ReportDetails/report-details.resolver";
import { ReportListComponent } from "./ReportsList/report-list.component";
export const reportRoutes: Routes = [
{
path: '',
pathMatch: 'full',
redirectTo: 'list'
},
{
path: 'view/:id',
component: ReportDetailsComponent,
data: {
pageTitle: 'Report detail'
},
resolve: {
report: ReportDetailsResolver
},
pathMatch: 'full'
},
{
path: 'list',
component: ReportListComponent,
data: {
pageTitle: 'Reports Lists'
},
pathMatch: 'full'
}
];
export const reportRouting = RouterModule.forChild(reportRoutes);
Campaign.routing
import { Routes, RouterModule } from '#angular/router';
import { CampaignDetailsComponent } from './campaignDetails/campaign-details.component'
import { CampaignDetailsResolver } from './campaignDetails/campaign-details.resolver'
import { CampaignListsComponent } from './campaignList/campaign-list.component'
export const campaignRoutes: Routes = [
{
path: 'view/:id',
component: CampaignDetailsComponent,
data: {
pageTitle: 'Campaign detail'
},
resolve: {
campaign: CampaignDetailsResolver
},
pathMatch: 'full'
},
{
path: 'lists',
component: CampaignListsComponent,
pathMatch: 'full'
}
];
export const campaignRouting = RouterModule.forChild(campaignRoutes);
The campaign module needs to use directive from the report Component, here is it's code :
#NgModule({
imports: [
CommonModule,
campaignRouting,
ReportModule
],
declarations: [CampaignDetailsComponent,CampaignListsComponent],
providers:[CampaignDetailsResolver]
})
export default class CampaignModule { }
Here is the problem : when i go to the route "/campaigns/view/:id" the router outlets loads content from the report component module and not from the campaign component...
A stupid solution would be to have unique route in each module (like /view Report/:id, /viewCampaign/:id... ) but i think i'm missing something in my app routing configuration....
Any idea on how to solve this kind of problem?
Thanks,
Olivier
I think the best solution here could be to change the way that you create your app hierarchy.
By using a "root" component for each module (report, campaign and stut), you could define "children" routes.
Here is an example from the "Routing and Navigation" Guide :
const crisisCenterRoutes: Routes = [
{
path: 'crisis-center',
component: CrisisCenterComponent,
children: [
{
path: '',
component: CrisisListComponent,
children: [
{
path: ':id',
component: CrisisDetailComponent
},
{
path: '',
component: CrisisCenterHomeComponent
}
]
}
]
}
];
#NgModule({
imports: [
RouterModule.forChild(crisisCenterRoutes)
],
exports: [
RouterModule
]
})
export class CrisisCenterRoutingModule { }
Also, i would recommend to follow a "Routing Module" way, like the one presented on the same guide :
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { HeroListComponent } from './hero-list.component';
import { HeroDetailComponent } from './hero-detail.component';
const heroesRoutes: Routes = [
{ path: 'heroes', component: HeroListComponent },
{ path: 'hero/:id', component: HeroDetailComponent }
];
#NgModule({
imports: [
RouterModule.forChild(heroesRoutes)
],
exports: [
RouterModule
]
})
export class HeroRoutingModule { }
I have a simple angular application and I am using Angular2 for the first time.
I am prompted with error in firefox console "EXCEPTION: Uncaught (in promise): Error: Cannot match any routes: 'books/huckleberry'"
book.component.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-directory',
templateUrl: './book.component.html',
styleUrls: ['./book.component.css']
})
export class BookComponent implements OnInit {
book: string;
constructor(private route: ActivatedRoute) {
this.book= route.snapshot.params['book'];
}
ngOnInit() {
}
}
app.routes.ts
import { Routes, RouterModule } from "#angular/router";
import { BookComponent } from "./book/book.component";
import { HomeComponent } from "./home/home.component";
const APP_ROUTES: Routes = [
{
path:'book',
component: BookComponent,
children: [
{ path: 'book/:book', component: BookComponent}
]
},
{ path: '', component: HomeComponent }
];
export const APP_ROUTES_PROVIDER = RouterModule.forRoot(APP_ROUTES);
app.module.ts
...
import { BookComponent } from './book/book.component';
import { RouterModule } from "#angular/router";
#NgModule({
declarations: [
AppComponent,
BookComponent,
HomeComponent,
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot([
{ path: '', component: HomeComponent },
{ path: 'book', component: BookComponent },
// { path: '**', component: PageNotFoundComponent }
]),
RouterModule.forChild([
{
path: 'book', //parent path
children: [
{
path: 'book/:book',
component: BookComponent,
}
]
}
])
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
When i access http://localhost:4200/book, there is no error.
But when i access http://localhost:4200/book/huckleberry, using Angular2 for the first time.
I am prompted with error in firefox console "EXCEPTION: Uncaught (in promise): Error: Cannot match any routes: 'book/huckleberry'"
Do you know how can i update app.module.ts?
I should be able to get {{book}} in book.component.html
I was able to solve this by the following codes below:
app.routes.ts
const APP_ROUTES: Routes = [
{ path:'directory', component: BookComponent },
{ path:'directory/:book', component: BookComponent },
{ path: '', component: HomeComponent }
];
app.module.ts
#NgModule({
declarations: [
AppComponent,
DirectoryComponent,
HomeComponent,
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot([
{ path: '', component: HomeComponent },
{ path: 'book', component: BookComponent },
{ path: 'book/:book', component: BookComponent }
// { path: '**', component: PageNotFoundComponent }
])
],
providers: [],
bootstrap: [AppComponent]
})
With the code above, i am now able to get the parameter and print it to the page via {{book}}