270

How can I get the current url in Angular 4? I've searched the web for it a lot, but am unable to find solution.

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule, Router } from '@angular/Router';

import { AppComponent } from './app.component';
import { TestComponent } from './test/test.component';
import { OtherComponent } from './other/other.component';
import { UnitComponent } from './unit/unit.component';

@NgModule ({
  declarations: [
    AppComponent,
    TestComponent,
    OtherComponent,
    UnitComponent
  ],

  imports: [
    BrowserModule,
    RouterModule.forRoot([
        {
            path: 'test',
            component: TestComponent
        },
        {
            path: 'unit',
            component: UnitComponent
        },
        {
            path: 'other',
            component: OtherComponent
        }
    ]),
  ],

  providers: [],
  bootstrap: [AppComponent]
})

export class AppModule { }

app.component.html

<!-- The content below is only a placeholder and can be replaced -->
<div>
    <h1>Welcome to {{title}}!!</h1>

    <ul>
        <li>
            <a routerLink="/test">Test</a>
        </li>
        <li>
             <a routerLink="/unit">Unit</a>  
        </li>
        <li>
            <a routerLink="/other">Other</a>
        </li>
    </ul>
</div>
<br/>
<router-outlet></router-outlet>

app.component.ts

import { Component} from '@angular/core';

@Component ({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent{
    title = 'Angular JS 4';
    arr = ['abcd','xyz','pqrs'];
}

other.component.ts

import { Component, OnInit } from '@angular/core';
import { Location } from '@angular/common';
import { Router } from '@angular/router';

@Component({
  selector: 'app-other',
  templateUrl: './other.component.html',
  styleUrls: ['./other.component.css']
})

export class OtherComponent implements OnInit {

    public href: string = "";
    url: string = "asdf";

    constructor(private router : Router) {}

    ngOnInit() {
        this.href = this.router.url;
        console.log(this.router.url);
    }
}

test.component.ts

import { Component, OnInit } from '@angular/core';
import { Location } from '@angular/common';
import { Router } from '@angular/router';

@Component({
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.css']
})

export class TestComponent implements OnInit {
    route: string;
    currentURL='';

    constructor() { 
        this.currentURL = window.location.href; 
    }

    ngOnInit() { }
}

Right now I am getting console issue after clicking on other link

ERROR Error: Uncaught (in promise): Error: No provider for Router!
VLAZ
  • 26,331
  • 9
  • 49
  • 67
  • Which url ??? browser url and please add some code the things you tried in so to understand you question in more details – mayur Jul 19 '17 at 08:29
  • Yes, current page url in browser –  Jul 19 '17 at 08:30
  • 1
    @MaciejTreder : [link](https://stackoverflow.com/questions/34597835/how-to-get-current-route) gone through this link already, it didn't worked. –  Jul 19 '17 at 08:53
  • Ok. Got your point. Did you try the solution from the answer? – Maciej Treder Jul 19 '17 at 08:54
  • How to access **this.route** variable in app.component.html view file? I want to echo current url in app.component.html file. `export class TestComponent implements OnInit { route: string; constructor(location: Location, router: Router) { router.events.subscribe((val) => { **this.route** = location.path(); }); } ngOnInit() { } }` –  Jul 19 '17 at 09:13
  • 1
    you can use as import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app'; currentURL=''; constructor() { this.currentURL=window.location.href; } } – Vindhyachal Kumar Jul 19 '17 at 09:17
  • @VindhyachalKumar: thanks a lot. It worked, by interpolating **{{this.currentURL}}** in view file. –  Jul 19 '17 at 09:21
  • @NilamDhok: I have added the same code in my answer. You can mark it as answer. – Vindhyachal Kumar Jul 19 '17 at 10:41
  • 1
    You got a typo in `import { RouterModule, Router } from '@angular/Router';` it should be `@angular/router`. – Maciej Treder Jul 19 '17 at 13:37
  • 1
    I tried to reproduce your issue in plunkr. Everything works: https://plnkr.co/edit/0x3pCOKwFjAGRxC4hZMy?p=preview – Maciej Treder Jul 19 '17 at 13:53

3 Answers3

468

With pure JavaScript:

console.log(window.location.href)

Using Angular:

this.router.url

import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
    template: 'The href is: {{href}}'
    /*
    Other component settings
    */
})
export class Component {
    public href: string = "";

    constructor(private router: Router) {}

    ngOnInit() {
        this.href = this.router.url;
        console.log(this.router.url);
    }
}

The plunkr is here: https://plnkr.co/edit/0x3pCOKwFjAGRxC4hZMy?p=preview

Maciej Treder
  • 11,866
  • 5
  • 51
  • 74
  • 2
    Got error : Property 'router' does not exist on type ' :( –  Jul 19 '17 at 10:30
  • 2
    Did you provide router to the component constructor? – Maciej Treder Jul 19 '17 at 11:16
  • `import { Component, OnInit } from '@angular/core'; import { Location } from '@angular/common'; import { Router } from '@angular/router'; @Component({ selector: 'app-other', templateUrl: './other.component.html', styleUrls: ['./other.component.css'] }) export class OtherComponent implements OnInit { public href: string = ""; constructor(protected router : Router) {} ngOnInit() { this.href = this.router.url; console.log(this.router.url); } }` –  Jul 19 '17 at 11:19
  • 1
    Do you have RouterModule imported? Check out this plunker: https://plnkr.co/edit/bmT3HSXdTmgAguiIL6zE?p=preview – Maciej Treder Jul 19 '17 at 11:34
  • 1
    Did you check plunker? Is it working on your end? – Maciej Treder Jul 19 '17 at 12:02
  • Yes I checked plunker. Even imported RouterModule in app.module.ts file, but now I'm getting error like: ERROR Error: Uncaught (in promise): Error: No provider for Router! **app.module.ts** `ERROR Error: Uncaught (in promise): Error: No provider for Router! Error: No provider for Router!` in console. –  Jul 19 '17 at 12:50
  • 1
    How did you import RouterModule? All in all, do you really need route from `router`? `window.location.href` is not enough in your case? – Maciej Treder Jul 19 '17 at 12:59
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/149607/discussion-between-maciej-treder-and-nilam-dhok). – Maciej Treder Jul 19 '17 at 13:07
  • 1
    @MaciejTreder this method `this.router.url` you mentioned will be trigger when page is reloading. is there any other way to get path `URL` without reloading page in `Angular 4` ? – Fai Zal Dong Nov 29 '17 at 04:10
  • @FaiZalDong Yes. It is. I will update my answer in near future. So far you can find example in my boilerplate, here: https://github.com/maciejtreder/angular-universal-pwa/commit/625fbd7bfca089fecadb12d4b024dacd4348394b – Maciej Treder Nov 29 '17 at 13:46
  • 202
    `window.location.href` is returning the absolute url of the page (including protocol and domain) while `this.router.url` is returning the relative path inside the application... I really do not understand how it is possible that this is the accepted answer as this solution is returning 2 completely different results!!! I also do not understand how it is possible that is marked as duplicated as the linked question is asking for the route url while here the question is asking for the absolute path – Ferie Dec 03 '18 at 17:49
  • @Ferie comment above it correct. inaccurate answer – Kim Gentes Aug 04 '20 at 18:03
  • this.router.url doesn't work as it is. follow this https://stackoverflow.com/questions/45320416/angular-router-url-returns-slash – Avinash Aug 09 '20 at 06:25
  • 1
    While in fact I'm on some page of my Angular app, `this.router.url` for a menu subcomponent returns me '\' each time... The truth is somewhere else... – Alexander Jun 15 '21 at 15:35
  • Well, one way it can happen, @Ferie, is that browsers and angular and JS evolve over time. Perhaps at the time of the answer, the answer was correct from the perspective of angular and browsers at the time? Otherwise, I'm SMH with you. – Thomas Carlisle Nov 02 '21 at 16:42
  • Thank you @Richard it worked for what I initially needed – Royer Adames Nov 19 '21 at 18:15
  • This is not returning the full url – Dani Villanueva Jul 20 '22 at 14:16
  • Wrong waye it's return just "/" waste of time – Siraj Ali Dec 30 '22 at 15:28
  • Downvoted because it does not answer the question; A "full URL" implies at least a protocol, host and path, but `router.url` returns only the path part of the full URL. – KrisW Jul 03 '23 at 08:23
80

You can make use of location service available in @angular/common and via this below code you can get the location or current URL

import { Component, OnInit } from '@angular/core';
import { Location } from '@angular/common';
import { Router } from '@angular/router';

@Component({
  selector: 'app-top-nav',
  templateUrl: './top-nav.component.html',
  styleUrls: ['./top-nav.component.scss']
})
export class TopNavComponent implements OnInit {

  route: string;

  constructor(location: Location, router: Router) {
    router.events.subscribe((val) => {
      if(location.path() != ''){
        this.route = location.path();
      } else {
        this.route = 'Home'
      }
    });
  }

  ngOnInit() {
  }

}

here is the reference link from where I have copied thing to get location for my project. https://github.com/elliotforbes/angular-2-admin/blob/master/src/app/common/top-nav/top-nav.component.ts

Lalit Sachdeva
  • 6,469
  • 2
  • 19
  • 25
  • You can just emit the first event using first() operator: `router.events.pipe(first()).subscribe((val) => {...});` – Nicolas Bodin Jun 11 '21 at 09:22
  • The only concern is that when I console.log it runs multiple times. – Royer Adames Nov 19 '21 at 18:38
  • You can also write it like this: router.events.subscribe((val) => { const thereIsAPath = location.path() != ''; const defaultPath = '/'; const currentPath = location.path(); thereIsAPath ? this.changePageBackground(currentPath) : this.changePageBackground(defaultPath); }); – Royer Adames Nov 19 '21 at 19:36
  • constructor(private router: Router) {} ngOnInit(): void { this.router.events.subscribe(event => { if (event instanceof NavigationEnd) { this.currentUrl = event.url; } }); } – Baran Goodarzi Jul 31 '22 at 05:47
6

other.component.ts

So final correct solution is :

import { Component, OnInit } from '@angular/core';
import { Location } from '@angular/common';
import { Router } from '@angular/router'; 

/* 'router' it must be in small case */

    @Component({
      selector: 'app-other',
      templateUrl: './other.component.html',
      styleUrls: ['./other.component.css']
    })

    export class OtherComponent implements OnInit {

        public href: string = "";
        url: string = "asdf";

        constructor(private router : Router) {} // make variable private so that it would be accessible through out the component

        ngOnInit() {
            this.href = this.router.url;
            console.log(this.router.url);
        }
    }
  • 3
    Could you explain why this is the correct solution? I would prefer to get a array of type `UrlSegment[]` instead to work with it with the `Router` – Mick Jan 15 '19 at 10:57
  • @ndgeek Better would be to have `public href: string = ""` replaced by a `get` property. This way there's no need to assign the value in `ngOnInit` whilst also having an always up to date router URL. As such: `get href(); string { return this.router.url; }`. Also there's no need as setting it `public` because that's the default. – Ruben Szekér Jan 31 '21 at 03:37