I'm trying to get the data from a Router whenever the Route changes but I'm not having success. Here I set the asdf
property
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
LoginComponent,
DashboardComponent,
OverviewComponent,
],
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot([
{ path: '', pathMatch: 'full', redirectTo: '' },
{ component: LoginComponent, path: 'login' },
{
children: [
{ path: '', pathMatch: 'full', redirectTo: 'overview', data: { asdf: 'hello' } },
{ component: OverviewComponent, path: 'overview', data: { asdf: 'hello' } },
], component: DashboardComponent,
path: '',
},
]),
],
})
export class AppModule { }
And here I can get the URL from the router when the route changes but asdf
is undefined :(
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { ActivatedRoute, NavigationEnd } from '@angular/router';
@Component({
selector: 'cs-map',
styleUrls: ['map.component.css'],
templateUrl: 'map.component.html',
})
export class MapComponent implements OnInit {
private routerSub;
constructor(private router: Router, private activatedRoute: ActivatedRoute) { }
public ngOnInit() {
this.router.events.subscribe((val) => {
if (val instanceof NavigationEnd) {
let url = val.url;
console.log(this.activatedRoute.snapshot.data['asdf']); // data is defined but asdf is not :(
}
});
}
}
How can I get asdf
's value?
Edit: I'm navigating to /overview
Here is a modified example using @Neelavar link example.
It might look long but it's simple, be patient, if you stick through it, it should work. Just following the steps outlined should take a few minutes.
Full Explanation for my setup, for beginners
You should already know how to create components and setup routing, I won't explain that in depth.
1. Setup Data Property in Routes Array
In your routes array (you will find this either in app.module.ts or app-routes.module.ts or in some cases a routes.ts file).
If you can't find this, check basic routing setup in: - angular docs - a video as well
a basic setup is all you need!
Add the data property like so (you will need to generate the home component):
2. Create a class
RouteData.ts, I have it in the same folder space as app.module.ts
This is just to add types for using the observable in typescript, the IDE can then autocomplete "title" or "id" or "animation" for me if I add that to the data class later.
3. Import the following into app.component.ts
Then above the constructor code, declare the variable
Then inside the constructor
4. Then inside ngOnInit
Explanation of code adapted from @Tuizi link Example Comment:
For every event from router, filter only for the NavigationEnd event (when the router has completed navigation).
Then map (return) the currently activatedRoute.
Map the activatedRoute to the firstChild (The first child of this route in the router state tree).
Then a switchMap emits the data of this route, use a switchMap because each "data" that is emitted is an observable, the switch map will cancel the old observable when a new one is emitted, saving memory.
Map (return) the data object, assign it a type of RouteData.
Finally you can use this Observable in a template using async pipe
*A note: "async as" breaks type checking in the template at the moment :(
github issue
The following is updated to work with rxjs v6
If you are hitting the route the first time you load the route in your browser, ActivatedRoute will have the current data. But if you then click on something which causes a second router navigation, the ActivatedRoute instance for that second route will have the original route's information. This could be due to to the fact that it was the ActivatedRoute at the time it was injected into the constructor.
However there is an updated instance of ActivatedRouteSnapshot associated with the ActivationEnd event, so you can access the data like this:
Without while loop
data in the routes must be an array of objects rather than just object so define them like this
Now to retrieve it use this code in your components constructor