How to list / output all routes in @Routes in my Angular2 App

TypescriptAngular

Typescript 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMike SavView Question on Stackoverflow
Solution 1 - TypescriptAnand RockzzView Answer on Stackoverflow
Solution 2 - TypescriptZolcsiView Answer on Stackoverflow
Solution 3 - TypescriptJosh1billionView Answer on Stackoverflow
Solution 4 - TypescriptOMANSAKView Answer on Stackoverflow
Solution 5 - TypescriptAdrian PaulView Answer on Stackoverflow
Solution 6 - Typescriptmichael_hookView Answer on Stackoverflow
Solution 7 - TypescriptVascoView Answer on Stackoverflow
Solution 8 - Typescriptjenson-button-eventView Answer on Stackoverflow
Solution 9 - TypescriptjbastiasView Answer on Stackoverflow
Solution 10 - TypescriptPrithvi UppalapatiView Answer on Stackoverflow