25

I'm trying to get the current router path by using Router, but when i do console.log(this.router.url) it returns "/", although i'm on the "/login". But when i'm consoling the entire this.router object, there is the property url which has value "/login".

here is my code from app.component.ts

export class AppComponent implements OnInit{
  constructor(private router: Router) {}

  ngOnInit(){
    console.log(this.router);
  }

}

app.module.routing.ts

import {NgModule} from '@angular/core';
import {PreloadAllModules, RouterModule, Routes} from '@angular/router';

import {NotFoundComponent} from './not-found/not-found.component';
import {AuthGuard} from './auth/auth-guard.service';

const appRoutes: Routes = [
  { path: '', loadChildren: './first/first.module#FirstModule'},
  { path: 'login', loadChildren: './login/login.module#LoginModule'},
  { path: '404', component: NotFoundComponent, canActivate: [AuthGuard] },
  { path: '**', redirectTo: '/404'}
];

@NgModule({
  imports: [RouterModule.forRoot(appRoutes, {preloadingStrategy: PreloadAllModules})],
  exports: [RouterModule]
})
export class AppModuleRouting {}

and the FirstModule routing:

import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';

import {FirstComponent} from './first.component';
import {AuthGuard} from '../auth/auth-guard.service';

const firstRoutes: Routes = [
  { path: '', component: FirstComponent, canActivate: [AuthGuard], children:[
    { path: '', loadChildren: './content-container/container.module#ContainerModule' }
  ]}
];
@NgModule({
  imports: [RouterModule.forChild(firstRoutes)],
  exports: [RouterModule]
})
export class FirstRoutes {}
sandum
  • 662
  • 5
  • 12
  • 22
  • This seems to be the problem. https://stackoverflow.com/questions/52143306/unable-to-get-the-path-nor-url-from-angular-router/52143966#52143966 – Gary Sep 03 '18 at 06:09
  • Check the demo https://stackblitz.com/edit/angular-xgahsx?file=src%2Fapp%2Fapp.component.ts – Gary Sep 03 '18 at 06:10

6 Answers6

31

Instead of trying to use Router (which is not ready to give you final route at this moment of navigation lifecycle), you can use Location service (https://angular.io/api/common/Location) and its method path, which will give you the url without base href. On the contrary, window.location.pathname is not aware of your angular toys and will give you path including base href.

import { Location } from '@angular/common';

export class AppComponent implements OnInit {
  constructor(private location: Location) {}

  ngOnInit(){
    console.log(this.location.path());
  }

}
carecki
  • 663
  • 5
  • 8
11

I have the same issue. The router.url returns a slash because when ngOnInit runs on the main app component, the route is the root. I got the correct value for the url by doing this.

  this.router.events
  .pipe(
    filter(e => e instanceof NavigationEnd)
  )
  .subscribe( (navEnd:NavigationEnd) => {
    console.log(navEnd.urlAfterRedirects);
  });

Hope that helps. This did not work with Angular Universal however... still trying to figure that out.

Reza Kajbaf
  • 357
  • 3
  • 9
1

Type 1.We can also use window.location.pathname

Type 2.constructor(router: Router) { 

      router.events.subscribe((url:any) => console.log(url));

      console.log(router.url);  // to print only path eg:"/login"
}
1

if you want to get the url whenever you click on a new link/page you should use this:

this.router.events.subscribe((routerData) => {
      if(routerData instanceof ResolveEnd){ 
         if(routerData.url === 'your url'){
           //Do something
         }
    } 
})
NXT Dev
  • 21
  • 3
0

Though this is 4 years old me and others will find it when looking for this issue. I had this problem while checking urls in the AuthGuard CanActivate interfaced class. For me the answers did not work, since at the point the guard is checking the URL, it is not available in Location nor in router.url. This worked for me:

const finalUrl = this.router.getCurrentNavigation()?.finalUrl;   
const isLoginPage = finalUrl?.root.children['primary'].segments[0]?.path === 'login';

this.router.getCurrentNavigation()?.finalUrl returns an UrlTree that might seem a bit complicated to use, my example above only works since "login" will always be my first segment. For a better understanding you should take a look at this example usage from the documentation:

@Component({templateUrl:'template.html'})
class MyComponent {
  constructor(router: Router) {
    const tree: UrlTree =
      router.parseUrl('/team/33/(user/victor//support:help)?debug=true#fragment');
    const f = tree.fragment; // return 'fragment'
    const q = tree.queryParams; // returns {debug: 'true'}
    const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
    const s: UrlSegment[] = g.segments; // returns 2 segments 'team' and '33'
    g.children[PRIMARY_OUTLET].segments; // returns 2 segments 'user' and 'victor'
    g.children['support'].segments; // return 1 segment 'help'
  }
}

https://angular.io/api/router/UrlTree#usage-notes

Tim Rasim
  • 594
  • 5
  • 19
-1

A quick and dirty solution is to wrap the code that uses the route in a setTimeout function with a timeout of 0.

e.g.

constructor(private router: Router) {
   setTimeout(this.logRoute, 0)
}

logRoute = () => {
   console.log(this.router.url)
}
  • No need to introduce race conditions with setTimeouts. Instead of that subscribe to the router events – com2ghz May 31 '22 at 08:21