3

Using angular/router 3.0.0-rc-2, I've been unsuccessful in retrieving data defined on a route from a service that I've created.

I can, however, retrieve the data from within the component defined for that route by injecting ActivatedRoute.

Here is my route:

export const CommonRoutes:RouterConfig = <Route[]>[
    {
        path: '',
        component: Home,
        data: {
            someKey: true
        }
    }
];

Here is the implementation that works, but is not the way I want to do this since I need the service to be able to handle this logic:

import {ActivatedRoute} from '@angular/router';

@Component({
    //component config...
});

export class Home {

    constructor(private _route: ActivatedRoute ) {
        this._route.data.subscribe(data => {
            console.log(data);
        })
    }
}

As you might expect, the Home component, when it loads, spits out:

{
    someKey: true
}

However, when moving this logic into a service that is injected on the main app component, it logs an empty object.

I have tried subscribing to router navigation events as well, which yields the same difference.

I am wondering if this is more of a paradigm problem. The ActivatedRoute documentation component description says: Contains the information about a component loaded in an outlet. The information is provided through the params, urlSegments, and data observables. - This leads me to think this will only make the route information available for components linked to a route.

So, I tried another approach- going through the router directly and using Router.routerState. The following is the service class code (which is where I need this logic to happen):

//...truncate imports/injectable decorator....

constructor(private _router:Router) {
    this._router.events
        .filter(evt => evt instanceof NavigationEnd)
        .subscribe(data => {
            console.log(_router.routerState.snapshot.root.data);
        });
}

This logs, seemingly unexpectedly, and empty object to the console.

Do I have some fundamental misunderstanding of how the router works/should be used? I feel like asking the router for the statically defined data on the current route should be a thing that components should be able to do. But maybe I'm nuts. However, for global logic that depends on a configuration variable that may or may not be present in every single component warrants doing this in a service.

Part of me feels like this kind of over-restrictive design was a flaw in Angular 1, where they prescribed what was "best for you" without taking into account the fact that real world situations don't always dictate the same architecture...

Not sure if it's relevant but I am running this project through webpack.

Any help is appreciated.

dudewad
  • 13,215
  • 6
  • 37
  • 46
  • Hi, did you found a solution for your problem? I am facing the same problem – Kosmonaft Sep 20 '16 at 00:34
  • @Kosmonaft No. It has been pointed out to me that "I was looking at routes the wrong way", though I actually disagree with how the router works on this one. The data is passed to the defined component only for the given route. An option would be to have your component import the service, and then notify the service of data it receives, but that's not exactly how I was looking to do it and in your case may or may not prove impossible. But, it's one way. – dudewad Sep 20 '16 at 00:36
  • I think a route == a route, it should give you the data regardless, end of story. But I'm sure I'm still misunderstanding something. – dudewad Sep 20 '16 at 00:37
  • Thank you. Unfortunately importing the service is not a solution for me because I have like an 40 components and somehow I want to tell on which component what kind of menu to load. So importing service in 40 components is not the cleanest solution for me. I have to find another way – Kosmonaft Sep 20 '16 at 00:40
  • Yep, same for me. Sorry! Wish that piece were easier. – dudewad Sep 20 '16 at 18:09
  • Hey, I believe I found the answer, which I posted below: http://stackoverflow.com/a/41409267/3112916 – buer Jan 13 '17 at 10:12
  • I am facing the same issue. At last, I gave up. – Bendy Zhang Mar 01 '23 at 06:11

1 Answers1

2

I believe this guy here gave a working example answer.

The static data seems to be obscured and buried, but it is present. In your case, that would be (notice the firstChild attribute):

constructor(private _router:Router) {
    this._router.events
        .filter(evt => evt instanceof NavigationEnd)
        .subscribe(data => {
            console.log(_router.routerState.root.firstChild.snapshot.data);
        });
}

Tried locally and it worked for me.

Community
  • 1
  • 1
buer
  • 330
  • 4
  • 11
  • Yes but with more complex routes this doens't work if I remember correctly. In the end, route data really is designed to be accessed by the route component. It's more of an architecture question. – dudewad Jan 17 '17 at 18:32