Code Whisperer
Code Whisperer

Reputation: 23652

Activated Route URL Always Empty

Consider the following service,

@Injectable()
export class SagasService {
    constructor(private route : ActivatedRoute, private router : Router ){
    router.events
        .filter(e => e instanceof NavigationStart)
        .subscribe(e=>{
            route.url.subscribe(a=>console.log(a[0].path));
        });
    }
}

Every time the route changes, the console.log() triggers. But, no matter what the route, the value is always "" (empty string).

What is wrong here?

Upvotes: 20

Views: 20014

Answers (4)

Nils Coussement
Nils Coussement

Reputation: 92

I see a lot of answers, but I think the following code might be a more 'polished' solution. All required values can be mapped in a way to fit your needs.

export class AppTitleComponent implements OnInit, OnDestroy {
public id$ : Observable<number>;

constructor(
    private _router: Router,
    private _activatedRoute : ActivatedRoute
) { }

ngOnInit() {
    this.id$ = GeneralFunctions.GetRouteValues({
        router : this._router,
        activatedRoute : this._activatedRoute
    }).pipe(
      map( d => +d.params.id)
    )
}

With the following function ready for use:

import { Injectable } from '@angular/core';
import { Router, ActivatedRoute, NavigationEnd, Params, Data } from '@angular/router';
import { filter, map } from 'rxjs/operators';
import { Observable } from 'rxjs';

@Injectable()
export class GeneralFunctions {
   constructor() {
   }

   public  static GetRouteValues({router, activatedRoute}: { 
        router: Router; 
        activatedRoute: ActivatedRoute; 
    })  : Observable<{
        route: ActivatedRoute;
        params: Params;
        data: Data;
    }> {
        return router
            .events
            .pipe(
                filter(e => 
                e instanceof NavigationEnd
            ),          
                map(() => 
                activatedRoute
            ),          
            map(route => {
                if (route.firstChild) {
                    route = route.firstChild;
                }
                return route;
            }),
            filter(route => 
                route.outlet === 'primary'
            ),
            map(route => { return  {
                route : route,
                params : route.snapshot.params,
                data : route.snapshot.data
            }})
        );
   }
}

Upvotes: 1

Chinna M
Chinna M

Reputation: 465

if you want to get the current URL, you can import the location import from angular/common as below

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

constructor(public location: Location ){ }

let currentUrl = this.location.path();

can be used in NavigationEnd subscriber

Upvotes: 17

Tomasz Kula
Tomasz Kula

Reputation: 16837

The definition of the ActivatedRoute is:

Contains the information about a route associated with a component loaded in an outlet. An ActivatedRoute can also be used to traverse the router state tree.

That means that if you inject it in the service, you will get the ActivatedRoute from the AppComponent. Which would always have the path of "".

You can traverse the state tree to find the last activated route like

this.router.events.pipe(
 filter(event => event instanceof NavigationEnd),
 map(() => this.activatedRoute),
 map(route => {
   while (route.firstChild) {
    route = route.firstChild;
   }
   return route;
  }),
  map(route => route.url)
 )
.subscribe( // ... do something with the url)

Upvotes: 32

shubham agarwal
shubham agarwal

Reputation: 177

The angular router sends the parameters to target component, and only it will be able to read those parameters.

However, you can use router events in service like RoutesRecognized to access the url parameters.

Upvotes: 3

Related Questions