Reputation: 3997
Suppose I have the following routes:
[
{
path: 'view',
children: [
{
path: ':id',
component: CustomerViewComponent,
resolve: {
customerViewData: CustomerResolve,
edit: ViewRouteResolve // Returns false
},
data: {
other: false
},
children: [
{
path: 'edit',
resolve: {
edit: EditRouteResolve // Returns true
},
data: {
other: true
}
},
{
path: '',
data: {
other: false
}
}
]
}
]
},
{ path: '', component: CustomerListComponent }
]
I want to use the CustomerViewComponent
for /view/ and /view/1/edit
The problem is I am unable to catch this data change in my component. I have tried with the resolve
or data
and I can't catch any changes...
This code will not trigger as expected:
this.route.data.subscribe(m => {
debugger; // Triggers only once the view loads, then never again
});
// This triggers quite often, but the data is always stale.
this.router.events.subscribe(m => {
console.log(this.route.snapshot.data['edit']);
console.log(this.route.snapshot.data['other']);
debugger;
});
Could this be a bug? my only work around is to look at the event NavigationEnd and analyze the .url string property...
Upvotes: 7
Views: 23051
Reputation: 44356
I will comment on the second part of your question:
This triggers quite often, but the data is always stale
In case you want to use routing events, You can listen to any of these events. But in your particular case you are only interested in NavigationEnd
. You can solve that by filtering the emitted value from the events observable using a pipe
and a filter
operator, so that your observer will only run on NavigationEnd
:
this.router.events.pipe(
filter(event instanceof NavigationEnd),
).subscribe(event => {
//... do something on navigation end...
});
Since you still used this.route.snapshot.data
in your observer, your data will not change or in your words be "stale" (no matter the event), it will refer always to the same static data, the data when ngOnInit
was first called.
Since the component is the same even after the route changes the component will not be destroyed and recreated, so ngOnInit
will not be called again.
This could be solved by using the ActivatedRoute
data observable route.data
instead of the route.snapshot.data
. You would have to subscribe or in case of your events solution you could use a mergeMap
operator:
this.router.events.pipe(
filter(event instanceof NavigationEnd),
mergeMap(this.route.data),
).subscribe(data => {
//...do something with your data...
});
But, since you are actually in a component you do NOT need to use any events, the data from the ActivatedRoute
instance observable will automatically re-emit the latest values on successful route navigation. So I suggest you more or less go with the answer from @DanielKucal which already suggests using the active route which is the right way. Just change the params
from his answer to data
and you will have your latest data:
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.route.data.subscribe(data => {
//...Do something with your data here...
}
}
Upvotes: 1
Reputation: 2060
When listening to router.events
the subscribe callback will get a few different types of events, multiple per route change. The ActivationStart
is the one that holds the route data
. Something like the following helped me:
this.router.events.subscribe(event => {
if (event instanceof ActivationStart) {
let data = event.snapshot.data;
this.titleService.setTitle(data['title'] || '_your_default_title_');
}
})
Upvotes: 8
Reputation: 9232
Try instead to use ActivatedRoute
from @angular/router
this.activatedRoute.params.subscribe(params => {
console.log(params['edit']);
console.log(params['other']);
});
Upvotes: 5