I have a ProfileModule
with the following routing :
// profile-routing.module
const routes: Routes = [
{
path: ':id',
component: ProfilePageComponent,
children: [
{
path: '',
redirectTo: 'feed',
pathMatch: 'full'
},
{
path: 'feed',
component: NewsFeedComponent
},
{
path: 'gallery',
component: MediasGalleryComponent
}
]
}
];
It works as follow:
ProfilePageComponent
fetches the profile ID in routing parameters and sends it to a ProfilePageService
NewsFeedComponent
and MediasGalleryComponent
receive the profile ID from ProfilePageService
Now, these two pages have been moved into two separate modules (respectively NewsModule
and MediasModule
), that I want to be lazy loaded in this routing. I cannot use ProfilePageService anymore. I came up with this solution :
// profile-routing.module
const routes: Routes = [
{
path: ':id',
component: ProfilePageComponent,
children: [
{
path: '',
redirectTo: 'news/:id/feed', // same as the parent ID
pathMatch: 'full'
},
{
path: 'news',
loadChildren: () => import('./news/news.module').then(m => m.NewsModule)
},
{
path: 'medias',
loadChildren: () => import('./medias/medias.module').then(m => m.MediasModule)
}
]
}
];
// news-routing.module
const routes: Routes = [{
path: ':profileId/feed',
component: NewsFeedComponent
}];
// medias-routing.module
const routes: Routes = [{
path: ':profileId/gallery',
component: MediasGalleryComponent
}];
This solution is not working, since I cannot get the profile ID parameter from parent route. How can I avoid this problem ?
Moreover, I don't like the fact that profile ID is duplicated in the URL. What would be the Angular way to do things ?
This is because the child modules just see the path to their module as their root path, which does not include the :id
. You can have a sharedService that is provided in your application root and reads the id on route changes. Then you can read that ID from within the child module.
@Injectable()
export class RouterStateService {
params$: Observable<Params>;
}
In your app component you can then do
@Component(...)
export class AppComponent {
constructor(private activatedRoute: ActivatedRoute, private routerState: RouterStateService) {}
ngOnInit() {
this.routerState.params$ = this.activatedRoute.params;
}
}
And in your child-component/module you can use it as
@Component(...)
export class WhatEverComponent {
constructor(private routerState: RouterStateService) {}
ngOnInit() {
this.routerState.params$.subscribe(console.log);
}
}
As always: Please do not forget to unsubscribe if you don't need the stream anymore.