I want to use hashing(#) for some routes and some routes without hashing(#). How can I implement this, e.g want to load attendance-report path with hashing and non-hashing both. Here is my app.module.ts file
import { Routes, RouterModule } from "#angular/router";
import { AuthGaurdService } from "./auth/auth-gaurd/auth-gaurd.service";
import { PageNotFoundComponent } from "./dashboard/pages/page-not-found/page-not-found.component";
const routes: Routes = [
{ path: "login", redirectTo: "dashboard", pathMatch: "full" },
{
path: "attendance-report/:token",
loadChildren: () =>
import("./dashboard/pages/agent-attendance/agent-attendance.module").then(
(m) => m.AgentAttendanceModule
),
},
{
path: "",
canActivate: [AuthGaurdService],
children: [
{ path: "", redirectTo: "dashboard", pathMatch: "full" },
{
path: "",
loadChildren: () =>
import("./dashboard/dashboard-layout.module").then(
(m) => m.AdminLayoutModule
),
},
],
},
{ path: "**", component: PageNotFoundComponent },
];
#NgModule({
imports: [
RouterModule.forRoot(routes, {
useHash: true,
relativeLinkResolution: "legacy",
})
],
exports: [RouterModule],
})
export class AppRoutingModule {}
Docs: Setting and handling query params and fragments
The following link adds a query parameter and a fragment to the generated URL:
<a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" fragment="education">
link to user component
</a>
By default, the directive constructs the new URL using the given query parameters. The example generates the link: /user/bob?debug=true#education.
You can instruct the directive to handle query parameters differently by specifying the queryParamsHandling option in the link. Allowed values are:
'merge': Merge the given queryParams into the current query params.
'preserve': Preserve the current query params.
For example:
<a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" queryParamsHandling="merge">
link to user component
</a>
See UrlCreationOptions#queryParamsHandling.
Related
I configured my app in two levels for nested routing as shown in the snapshot image.
the content of app modules is:
app.module.ts
#NgModule({
declarations: [
AppComponent,
DashboardComponent,
TeacherMembershipComponent,
StudentMembershipComponent,
RulesComponent,
ContactInfoComponent,
Page404Component,
UserProfileComponent,
NotificationsComponent,
GeneralComponent,
ReportComponent
],
// ...
and app-routing.module.ts
const routes: Routes = [
{
path: 'dashboard',
component: DashboardComponent
},
{
path: 'userProfile',
component: UserProfileComponent
},
{
path: 'general',
component: GeneralComponent
},
{
path: 'report',
component: ReportComponent
},
{
path: 'notifications',
component: NotificationsComponent
},
{
path: "department/:dep", loadChildren: () => import(`./branches/branches.module`).then(m => m.BranchesModule)},
{
path: 'aboutUs/rules',
component: RulesComponent
},
{
path: 'aboutUs/contactInfo',
component: ContactInfoComponent
},
{
path: 'membership/teacher',
component: TeacherMembershipComponent
},
{
path: 'membership/student',
component: StudentMembershipComponent
},
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
{ path: '**', component: Page404Component },
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
the second level is branches that its modules are:
branches.module.ts:
#NgModule({
declarations: [
BranchesComponent,
CoursesListComponent,
TeachersListComponent,
TeacherResumeComponent,
TeacherSelectionFormComponent,
Page404BranchesComponent
],
imports: [
CommonModule,
BranchesRoutingModule,
MaterialDesignModule
]
})
export class BranchesModule { }
and branches-routing.module.ts:
const routes: Routes = [
{ path: '', component: BranchesComponent, children: [
{
path: "coursesList/:branchCourses",
component: CoursesListComponent
},
{
path: "teacherSelection",
component: TeacherSelectionFormComponent
},
{
path: "teacherResume",
component: TeacherResumeComponent
},
{
path: 'coursesList', component: CoursesListComponent
},
{
path: '', redirectTo: 'coursesList', pathMatch: 'full'
},
{
path: '**', component: Page404BranchesComponent
},
]}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
till here, when one of links (departments) in sidenav of app.component.html is clicked, the branches.component is loaded in place of route-outlet of app.component and subscribes the parameters passed from app.component, and lists branches respected to each link.
baranch.component.ts:
export class BranchesComponent implements OnInit {
filteredBranches$!: Observable<Branch[]>;
filteredBranches!: Branch[];
constructor(private route: ActivatedRoute, private branchesService: BranchesService) {
}
activeTab: string=''
ngOnInit(): void {
this.route.paramMap.pipe(
switchMap((params: Params) => {return this.branchesService.getDepBranches(params['get']('dep')) })
).subscribe((branches) => {this.filteredBranches = branches; this.activeTab=this.filteredBranches[0].name});
}
}
and branch.component.html:
<nav mat-tab-nav-bar>
<a mat-tab-link *ngFor="let br of filteredBranches"
[routerLink]="['coursesList', br.code]"
routerLinkActive="activeLink"
(click)="activeTab = br.name"
[active]="activeTab == br.name"> {{ br.name }} </a>
</nav>
<router-outlet></router-outlet>
but, although links of branches are listed in template of branches.component, no courses respect to each branches are shown by coursesList.component which placed in router-outlet of branches.component, because it does not received any route parameter from branch.component, until one of branch link is clicked.
I expect that upon branches links are shown at the same time branches.component is loaded, bellow of them, the courses of the first branch are listed by coursesList.component placed in router-outlet of branches.component.
Whereas no one of branch links is clicked and no parameter passed to coursesList.component, nothing is shown. Therefore, is there a solution to active the first branch link as defualt and pass its courses parameters to coursesList component upon branches.component is loaded? Best regards.
I have angular project and I need when user type the URL like www.mysite.com/hisName , Take this name and add it to all routing pages in my project and the final result will be like www.mysite.com/hisName/home
this is my routing code
import { NgModule } from "#angular/core";
import { Routes, RouterModule } from "#angular/router";
import { AppComponent } from "./app.component";
const routes: Routes = [
{ path: "", redirectTo: "home", pathMatch: "full" },
{ path: "home", component: HomeComponent },
path: "supliers",
loadChildren: () =>
import("./supliers-container/supliers-container.module").then(
(mod) => mod.SupliersContainerModule
),
}
#NgModule({
imports: [RouterModule.forRoot(routes, { useHash: true })],
exports: [RouterModule],
})
export class AppRoutingModule {}
I think you are asking for something like a wildcard option? It does have to be defined as the last element.
const routes: Routes = [
{ path: "", redirectTo: "home", pathMatch: "full" },
{ path: "home", component: HomeComponent },
{ path: "supliers",
loadChildren: () =>
import("./supliers-container/supliers-container.module").then(
(mod) => mod.SupliersContainerModule
),
},
{ path "**", redirectTo: "home", pathMatch: "full" } // here
]
Note: if you add the wildcard, I don't think you need the first path option.
I was trying to navigate from a parent component (Core) using an url dynamically emitted from a child component (Menubar).
The problem is that the navigation is cancelled without any reason.
To find out if the problem came from the parent component, I implemented a button in the parent component navigating to a static url, and it worked!
Core template:
<app-menubar (onNavigation)="onMenubarNavigation($event)"></app-menubar>
<button type="button" (click)="navigate()">Navigate</button>
<router-outlet><router-outlet>
Core component:
onMenubarNavigation(urlSegments: string[]): void {
this.router.navigate(urlSegments);
}
navigate(): void {
let segments: string[];
segments = ['index', 'messages'];
this.router.navigate(segments);
}
Menubar template:
<a (click)="changeRoute(element.module.route)">
// element.module route is the string: "/messages"
Menubar component:
#Output() onNavigation = new EventEmitter<string[]>();
changeRoute(url: string): void {
let urlSegments: string[];
urlSegments = url.split('/');
urlSegments[0] = 'index';
this.onNavigation.emit(urlSegments);
}
App routing module:
const routes: Routes = [
{ path: 'login', loadChildren: '.\/auth\/auth.module#AuthModule' },
{ path: 'logout', loadChildren: '.\/auth\/auth.module#AuthModule' },
{ path: '', loadChildren: './theme/core/app.core.module#AppCoreModule', pathMatch: 'full' },
];
#NgModule({
imports: [RouterModule.forRoot(routes, { enableTracing: true })],
exports: [RouterModule]
})
export class AppRoutingModule { }
Core routing module:
const coreRoutes: Routes = [
{
path: '',
component: AppCoreComponent,
canActivate: [AuthGuard],
children: [
{
path: 'home',
loadChildren: '..\/home\/app.home.module#AppHomeModule'
},
{
path: 'index',
loadChildren: '..\/index\/app.index.module#AppIndexModule'
},
{
path: '',
redirectTo: 'index',
pathMatch: 'full'
}
]
}
];
#NgModule({
imports: [
RouterModule.forChild(coreRoutes)
],
exports: [
RouterModule
]
})
export class AppCoreRoutingModule {}
The angular routing debug shows that both urls are the same during navigation, using the one emitted by the child component or the static one, but when I navigate using the one emitted, the navigation is cancelled and I have no idea why...
Has someone ever encoutered this kind of trouble with the angular router?
I have an Angular2 project built with this Angular 2 Webpack Starter but I cannot get the fallback route to work correctly. In my app.routes.ts I have:
import { Routes } from '#angular/router';
import { HomeComponent } from './home';
import { DataResolver } from './app.resolver';
export const ROUTES: Routes = [
{
path: '',
component: HomeComponent
},
{
path: 'getstarted', loadChildren: './getstarted#GetStartedModule'
},
...
{
path: 'notfound', loadChildren: './notfound#NotFoundModule'
},
{
path: '**', loadChildren: './notfound#NotFoundModule'
},
];
The not found path above works correctly but the fallback route (**) does not work correctly. Instead of showing the NotFoundModule it does not load a module at all and I get no errors. However, when I do this it redirects correctly:
...
{
path: 'notfound', loadChildren: './notfound#NotFoundModule'
},
{
path: '**', redirectTo:'/notfound', pathMatch: 'full'
},
];
I do not want to redirect though because I do not want to change the url to /notfound by redirecting. How can I make my top version work or what else can I do to make this work?
So, I just tried it and it seems that you cannot use lazy routes to set your fallback page. This should work :
export const ROUTES: Routes = [
{
path: '',
component: HomeComponent
},
{
path: 'getstarted', loadChildren: './getstarted#GetStartedModule'
},
...
{
path: 'notfound', loadChildren: './notfound#NotFoundModule'
},
{
path: '**', component : NotFoundComponent
},
];
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 { }