61

I need to get my current route without params in Angular 2, I found a way to get the current route with params as follows:

 this.router.url

and then split it:

 this.router.url.split(';')[0]

But this looks as workaround, I think there should be better way?

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
Sabri Aziri
  • 4,084
  • 5
  • 30
  • 45
  • `this.dom.URL.split('?')[0]` -> where dom is instance of `DOCUMENT` – Pardeep Jain Aug 07 '19 at 17:59
  • 3
    The "angular" way would be to import Router from `@angular/router` and then *"simply"* use `this.router.parseUrl(this.router.url).root.children.primary.segments`. If the goal was to make as many developers as possible prefer Vue or React over Angular, it's a job very well done. Hat off, Angular architects! And no, providing subscriptions is not enough. What if I want to get the activated route params in a component created after route has changed (i.e: a modal)? You need to expose subscriptions as well as methods to get the current value. Make it easy to use for children! That's your goal! – tao Oct 10 '20 at 11:36

15 Answers15

54

To get current route without query parameters, you can use below mentioned single line:

this.router.url.split('?')[0] 
Prashant Pimpale
  • 10,349
  • 9
  • 44
  • 84
Yanusha Cooray
  • 615
  • 6
  • 2
42

parseTree from Router helps fetching the segments without any knowledge about url structure.

import { Router } from '@angular/router';
...
constructor(private router: Router) {}
...
const urlTree = this.router.parseUrl(url);
const urlWithoutParams = urlTree.root.children['primary'].segments.map(it => it.path).join('/');

Start from here. If you have secondary outlets adjust as required.

André Werlang
  • 5,839
  • 1
  • 35
  • 49
  • If `url` is `/`, there are no primary children. So, `urlWithoutParam` should be `/` if `urlTree.root.children.primary` is `undefined`. – Guido Flohr Jan 27 '20 at 12:51
26

For me, this is the cleanest solution I managed to do. I hope it helps

import { Router } from '@angular/router';
    
constructor(private router: Router){}

getUrlWithoutParams(){
   let urlTree = this.router.parseUrl(this.router.url);
   urlTree.queryParams = {}; 
   urlTree.fragment = null; // optional
   return urlTree.toString();
}
13

Short and simple pure js.

location.pathname
5

Native javascript will work to split the url into logical parts. Check out the "location" (or window.location) object. For example, using location at the url https://example.com/pathname1/pathname2?queryParam1=1&queryParam2=2 yields

location.origin === 'https://example.com/pathname1/pathname2'
location.href === 'https://example.com/pathname1/pathname2?queryParam1=1&queryParam2=2'
location.pathname === '/pathname1/pathname2'
location.search === '?queryParam1=1&queryParam2=2'
5

If you are using webpack, you can use the url polyfill module which comes bundled, along with the Angular Router module.

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import * as url from 'url'

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

  public constructor(public readonly router: Router) {}

  public ngOnInit() {
    const urlInfo = url.parse(this.router.url)
    console.log(urlInfo.pathname)
  }
}
Get Off My Lawn
  • 34,175
  • 38
  • 176
  • 338
3

I had a similar requirement, depending on which route I used to get the component I wanted different outcomes.

I found that activatedRoute.routeConfig.path was a great option and made it easy for me to see which route had been used.

constructor(private activatedRoute: ActivatedRoute) {}
ngOnInit() {
  if (this.activatedRoute.routeConfig.path === 'heroes/:id')
Ben Morris
  • 282
  • 3
  • 13
Des Horsley
  • 1,858
  • 20
  • 43
2

this could help you:

  1. Import Router:

    import { Router } from '@angular/router';
    
  2. Signature in the constructor:

    constructor(private _router: Router) {}
    
  3. Check the _router events property:

    this._router.events
        .subscribe(
            (url:any) => {
                let _ruta = "";
                url.url.split("/").forEach(element => {
                    if(element!=="" && _ruta==="")
                        _ruta="/"+element;
                    });
                console.log("route: "+_ruta); //<<<---- Root path
                console.log("to URL:"+url.url); //<<<---- Destination URL 
                console.log("from URL:"+this._router.url);//<<<---- Current URL
            }); 
    
Renats Stozkovs
  • 2,549
  • 10
  • 22
  • 26
eberlast
  • 160
  • 2
  • 7
1

To get current route without query parameters, you can use below mentioned single line:

this.url = this.url.substr(0, this.url.lastIndexOf("?"));
Temo Kiknadze
  • 269
  • 3
  • 8
1

this worked like a charm for me:

  currentUrl: string;

  constructor(private router: Router) {}

  ngOnInit() {
    const urlTree: UrlTree = this.router.parseUrl(this.router.url);
    const urlSegmentGroup: UrlSegmentGroup = urlTree.root.children['primary'];
    this.currentUrl = urlSegmentGroup ? urlSegmentGroup.segments.map((it) => it.path).join('/') : '';
  }
WIRN
  • 915
  • 1
  • 16
  • 31
0

In my case I needed to compare the previous route and the new route, when changing only the :id on the url via router.navigate. Since I wanted the path without the different ids, I got the original path of the route:

/* 
    Routes = [
        { path: 'main/details/:id', component: DetailComponent }
    ]

    previousRoute = '/main/details/1'
    newRoute      = '/main/details/2'
*/

this.routeSubscription = this.router.events.filter((event) => event instanceof ResolveStart)
                                           .pairwise() // returns previous and current events
                                           .subscribe((ev: [ResolveStart, ResolveStart]) => {

    let sameRoute = ev[0].state.root.firstChild.routeConfig.path == ev[1].state.root.firstChild.routeConfig.path ?
                       ev[0].state.root.firstChild.routeConfig.path : undefiend;
    if (sameRoute) {
        // Same routes, probably different ids 
        console.log(sameRoute) // gives 'main/details/:id'
    } else {
        // Different routes
    }
});
StinkyCat
  • 1,236
  • 1
  • 17
  • 31
0

I use locationStrategy like in accept answer but with .split() method. LocationStrategy work perfect in Angular 4 & Angular 5;

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

export class MyService {
    constructor(private locationStrategy: LocationStrategy) {
    }

    public getUrl(filters: FilterConfig[]): void {
        const url = this.locationStrategy.path();
        const urlArray = url.split('?');

        return urlArray[0];
    }
}

One more things you should carry about is to be sure that your <router-outlet> is properly initialize before you try to get locationStrategy.path(). If <router-outlet> isn't initialize any Angular services can't return URL and query params properly.

To be sure that you location strategy is initialize you can use subscribe method like:

this.router.events.subscribe((evt) => {
...
}

But in this case you trigger your function on each router change so you need to protect this case if it's unwanted.

kris_IV
  • 2,396
  • 21
  • 42
0

None of these worked for me.

There are many approaches to this, but in this case a guard was in place to stop users going to specific URL's. This worked fine except when URL's had parameters as the passed URL always contained all the parameters.

E.G: myPage/param1/param2

Or: myPage?param1=1&param2=2

In this case I'd want just myPage.

I coded the below, I don't like it, I'm sure it can be improved but haven't found anything else that works so far:

    let url: string = state.url;
    let urlParams: string[];

    if (url.includes("?")) {
        url = url.substr(0, url.indexOf('?'));
    } else {
        urlParams = route.url.toString().split(';')[0].split(',');

        if (urlParams.length > 1) {
            urlParams.shift(); // Remove first element which is page name

            // Get entire splitting on each param
            let fullUrlSegments: string[] = state.url.split('/');
            // Remove number of params from full URL
            fullUrlSegments = fullUrlSegments.slice(0, fullUrlSegments.length - urlParams.length);

            url = fullUrlSegments.join('/');
        }
    }

    alert(url);

state.url comes from the implementation for CanActivate (or inject Router).

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) Observable<boolean> { ... }
Ricky
  • 7,785
  • 2
  • 34
  • 46
0

You could use URL https://developer.mozilla.org/en-US/docs/Web/API/URL/URL

const url = new URL("https://example.org/route/test?test")
const path = url.origin + url.pathname

But does not work in Internet Explorer.

MisterMonk
  • 327
  • 1
  • 9
0

Using Angular PlatformLocation:

@Component{...}
// or
@Service{...}
export class Some {
constructor(private platformLocation: PlatformLocation) {
  console.log(this.platformLocation.pathname);
}

Felix
  • 3,999
  • 3
  • 42
  • 66