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 { }
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 am facing some issue while setting up the routing in the angular 8.
I am doing it like:
'company/:id/activity'
'company/:id/contacts'
did not get any params in activatedRoute:
this.activateRoute.params
.subscribe(param => console.log(param) )
Is there any luck to fix that?
Main Routing file:
{
path: 'company/:id',
children: [
{
path: '',
loadChildren: () => import('#app/features/company-view/company-view.module').then(m => m.CompanyViewModule)
}
]
}
Lazy loaded routing file:
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { CompanyViewComponent } from '#app/features/company-view/company-view.component';
import { PendingChangesGuard } from '#app/shared/guards';
import { CompanyActivityComponent } from './company-activity/company-activity.component';
const routes: Routes = [
{
path: '',
component: CompanyViewComponent,
children: [
{
path: '',
redirectTo: 'view'
},
{
path: 'activity',
component: CompanyActivityComponent,
data: {
title: "Company Activity"
}
}
]
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class CompanyViewRoutingModule { }
if I use routing below then it works fine:
const routes: Routes = [
{
path: '',
component: CompanyViewComponent,
children: [
{
path: ':id/activity',
component: CompanyActivityComponent,
data: {
title: "Company Activity"
}
},
{
path: '**',
redirectTo: 'activity'
}
]
}
];
then how do I set the default routing to :id/activity ?
So. You want to pass variables for your component through the routing.
In your routes.ts is oke like this path: 'company/:id/:activity'.
Then you need to give it to your component.
I'm using this: id = this.route.snapshot.params['id'] or activity = this.route.snapshot.params['activity'].
From here you can pass through for another component or whatever you want.
Ex:
<app-testcomponent
[id]="id"
[activity]="activity">
</app-testcomponent>
I'm not seeing a route for this: "view".
{
path: '',
redirectTo: 'view'
}
I changed it to "activity" and changed it to your catch all route for that section of the tree. I also refactored your routes a little bit, please look at both:
Main Route
{
path: 'company',
children: [
{
path: '',
loadChildren: () => import('#app/features/company-view/company-view.module').then(m => m.CompanyViewModule)
}
]
}
Child Routes
const routes: Routes = [
{
path: ':id',
component: CompanyViewComponent,
children: [
{
path: 'activity',
component: CompanyActivityComponent,
data: {
title: "Company Activity"
}
},
{
path: '**',
redirectTo: 'activity'
}
]
}
];
I am currently working on creating a CI/CD pipeline for a .net core and angular application.
One of the steps in the build is to use the npm build command.
In this step, I get the following error:
This is what my app-routing module looks like:
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { CanActivateGuard } from './shared/guards/can-activate.guard';
import { HomeComponent } from './home/home.component';
import { UnauthorizedComponent } from './unauthorized/unauthorized.component';
import { ForbiddenComponent } from './forbidden/forbidden.component';
import { NotFoundComponent } from './not-found/not-found.component';
import { ClientModule } from './client/client.module';
import { UserModule } from './user/user.module';
import { SuperUserModule } from './super-user/super-user.module';
import { LicenseModule } from './license/license.module';
import { IsAdminGuard } from './shared/guards/Admin/isAdmin.guard';
import { ApplicationsComponent } from './applications/applications.component';//
import { DashboardComponent } from './dashboard/dashboard.component';
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'applications', component: ApplicationsComponent }, //Added By Kumar Arpit For Role Based Redirection Functionality
{ path: 'dashboard', component: DashboardComponent }, //Added By Kumar Arpit For Dashboard
{ path: 'unauthorized', component: UnauthorizedComponent },
{ path: 'forbidden', component: ForbiddenComponent },
{ path: 'clients', loadChildren: () => ClientModule, canActivate: [IsAdminGuard] },
{ path: 'users', loadChildren: () => UserModule, canActivate: [IsAdminGuard]},
{ path: 'superusers', loadChildren: () => SuperUserModule, canActivate: [IsAdminGuard] },
{ path: 'license', loadChildren: () => LicenseModule, canActivate: [IsAdminGuard] },
{ path: '**', component: NotFoundComponent },
];
#NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ]
})
export class AppRoutingModule { }
Please help me figure out what might be going wrong. Thank you.
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' }
So, I'm building an Angular 4 app that I want all routes to be protected (except for the login route of course). I'm trying to use feature modules and feature module routing. So, imagine something like this:
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { AuthGuardService } from './auth/auth-guard.service';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';
import { ProtectedRouteComponent } from './protected-route/protected-route.component';
const routes: Routes = [
{ path: 'login', component: LoginComponent }, // no auth guard for login
{
path: '',
canActivate: [AuthGuardService],
children: [
{
path: '',
children: [
{ path: 'register', component: RegisterComponent },
{ path: 'protected', component: ProtectedRouteComponent }
]
}
]
}
];
#NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}
, for the root module, and then a users feature module routing config like:
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { UsersComponent } from './users.component';
const routes: Routes = [
{ path: 'users', component: UsersComponent }
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class UsersRoutingModule {}
What would be the best way to:
Keep using feature module routing, and
Apply the route guards to the users feature module routing without replicating the canActivate guard? Is there any way I can pass it on to the users feature module routing from the root routing module?
Thanks,
Iraklis
Was looking for the same and the solution I found involves the following steps:
Do not import your feature module via app modules
Instead import the feature module as part of your app module routes
{
path: '',
canActivate: [AuthGuardService],
children: [
{
path: '',
children: [
{ path: 'register', component: RegisterComponent },
{ path: 'protected', component: ProtectedRouteComponent }
]
},
{
path: '',
children: () => UsersModule
}
]
}
One thing to consider:
Other modules will NOT have access to your UserModule's components and services (until you have visited one of the /users routes)
This might not be a problem as your modules might already be well separated