How to list / output all routes in @Routes in my Angular2 App
TypescriptAngularTypescript Problem Overview
I have a quick question. I'm currently looking through https://angular.io/docs/ts/latest/api/router/Router-class.html but I was wondering, in my Angular2's main.ts
I have my routes defined thus:
@Routes([
{ path: '/', component: HomeComponent },
{ path: '/about-me', component: AboutMeComponent },
{ path: '/food', component: FoodComponent },
{ path: '/photos', component: PhotosComponent },
{ path: '/technology', component: TechnologyComponent },
{ path: '/blog', component:Blogomponent },
])
Now in a component elsewhere I import the Router class. In my component (or the component template) I would like to loop through all my routes defined or just be able to access them. Is there a built in way to do this? Like some function that returns an object array? Here is a crude idea of what I want...
@Component({
selector: 'ms-navigation',
templateUrl: 'src/navigation/navigation.template.html',
directives: [ ROUTER_DIRECTIVES ]
})
export class NavigationComponent {
constructor(private router:Router) {
// what can I do here to get an array of all my routes?
console.log(router.routes); ????
}
}
Typescript Solutions
Solution 1 - Typescript
Here is a better version which will list all possible routes (fixed according to comments):
import { Router, Route } from "@angular/router";
constructor(private router: Router) { }
ngOnInit() {
this.printpath('', this.router.config);
}
printpath(parent: String, config: Route[]) {
for (let i = 0; i < config.length; i++) {
const route = config[i];
console.log(parent + '/' + route.path);
if (route.children) {
const currentPath = route.path ? parent + '/' + route.path : parent;
this.printpath(currentPath, route.children);
}
}
}
Solution 2 - Typescript
Apparently there is a very compact way to do it:
constructor(private router: Router) {}
ngOnInit() {
console.log('configured routes: ', this.router.config);
}
Solution 3 - Typescript
If you only need the route paths as strings, you can find them by iterating over your Router
object's config
array.
for (var i = 0; i < this.router.config.length; i++) {
var routePath:string = this.router.config[i].path;
console.log(routePath);
}
Solution 4 - Typescript
I am using this comp. to get all routes in angular 9
import { Compiler, Component, Injector, OnInit } from '@angular/core';
import { Route, Router } from '@angular/router';
@Component({
templateUrl: './sitemap.component.html'
})
export class SiteMapComponent implements OnInit {
public urls: string[] = [];
constructor(private _router: Router, private compiler: Compiler, private injector: Injector) {
}
ngOnInit() {
this._router.config.forEach(i => {
this.getPaths(i);
})
}
getPaths(route: Route, parent: string = '') {
if (route.redirectTo) {
return;
}
if (route.children) {
route.children.forEach(i => {
this.getPaths(i, parent + route.path);
});
}
else if (route.loadChildren) {
(<any>this._router).configLoader.load(this.injector, route).subscribe(i => {
i.routes.forEach(j => {
this.getPaths(j, parent + route.path)
});
});
}
else if (route.path != null) {
this.setPath(route.path, parent);
}
}
setPath(path, parent) {
let fullPath: string;
if (path != null) {
if (parent) {
fullPath = `/${parent}/${path}`;
}
else {
fullPath = `/${path}`
}
}
this.urls.push(fullPath)
}
}
Solution 5 - Typescript
This comes as an extension to @Anand Rockzz's answer.
Was written for Angular 6.0 and list all possible routes including the lazy ones (https://angular.io/guide/lazy-loading-ngmodules):
UPDATED
As @Daniel B mentioned:
> [...] this no longer works with Angular 8.0
import { Route } from '@angular/router';
import { LoadedRouterConfig } from '@angular/router/src/config';
printPaths(parent: string, routes: Route[]) {
const getFullPath = (path?: string) => {
if (path) {
return parent + '/' + path;
}
return parent;
};
for (let i = 0; i < routes.length; i++) {
const route = routes[i];
const fullPath = getFullPath(route.path);
console.log(parent + '/' + route.path, route.component);
if (route.children /*&& route.children.length > 0*/) {
this.printPaths(fullPath, route.children);
}
if (route.loadChildren && route.loadChildren.length > 0) {
var routerConfig = <LoadedRouterConfig>(<any>route)['_loadedConfig'];
if (routerConfig) {
this.printPaths(fullPath, routerConfig.routes);
}
}
}
}
Solution 6 - Typescript
For @angular version 2.00 I was able to find a list of the children through the routeConfig property.
Here is an example of my component. Note, I'm accessing the children via the 'parent' property as the component is actually one of the children as I'm rendering it in the child router-outlet.
import { Component } from '@angular/core';
import {Route, ActivatedRoute, Router} from "@angular/router";
@Component({
selector: 'list',
template: require('./list.component.html')
})
export class ListComponent {
children = new Array<RouteLink>();
constructor(private router: Router, private activatedRoute: ActivatedRoute) {
for (let child of activatedRoute.parent.routeConfig.children) {
if (child.path && child.data["breadcrumb"]) {
this.children.push(new RouteLink(child.path, child.data["breadcrumb"]));
}
}
}
}
export class RouteLink {
constructor(private path: string, private name: string) { }
}
Solution 7 - Typescript
I’ve created a util function based on the answer of @OMANSAK. Tested with Angular 12 and lazy loaded modules.
import { Injector } from '@angular/core';
import { Router, Route } from '@angular/router';
const routerUrls: string[] = [];
async function getPaths(router: Router, injector: Injector, route: Route, parent: string = ''): Promise<void> {
if (route.redirectTo) {
return;
}
if (route.children) {
for (const childRoute of route.children) {
await getPaths(router, injector, childRoute, parent + route.path);
}
} else if (route.loadChildren) {
const lazyConfig = await router['configLoader'].load(injector, route).toPromise();
for (const childRoute of lazyConfig.routes) {
await getPaths(router, injector, childRoute, parent + route.path);
}
} else if (route.path !== null) {
if (route.path !== '') {
routerUrls.push(parent ? `/${parent}/${route.path}` : `/${route.path}`);
} else {
routerUrls.push(parent ? `/${parent}` : '');
}
}
}
/**
* Returns routes of the app via the Angular Router.
*
* Important: The fallback route in the app module (path: "**")
* has to be the last element in your top level app-routing-module.
*
* @param router Angular Router
* @param injector Angular Injector
* @returns Routes of the app
*/
export async function getAllPaths(router: Router, injector: Injector): Promise<string[]> {
const topLevelRoutes = router.config.slice(
0,
router.config.findIndex((route) => route.path === '**') ?? router.config.length - 1
);
for (const i of topLevelRoutes) {
await getPaths(router, injector, i);
}
return routerUrls;
}
Solution 8 - Typescript
From Angular 9+, you can look at a component that has a Router injected, via the browser console:
window.ng.getComponent(document.querySelector('app-employee-overview')).router.config[0].children
Solution 9 - Typescript
You run into issues using this solution if you have Lazy routes. I made a simple bash command to show the routing information:
cd /path/to/app
for r in $(find src -name "*.routes.ts"); do
echo $r; grep "path:\|component:\|loadChildren:" $r;
done
Solution 10 - Typescript
if you want to look at the available route by importing into a component.
assign your routes to a constant like below
const appRoutes: Routes = [
{
path: 'asd',
component: asdComponent
},
{
path: 'ar',
component: arComponent
}
];
export const routing = RouterModule.forRoot(appRoutes);
here you will be able to export the routes
import the const routing
import { routing } from './app.routing';
export class AppComponent {
route=routing;
/// route.providers is an array which internally contains the list of routes provided
console.log(route.providers);
}
this is just to find the available routes. not recommendable to implement logic based on this