Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular lazy load with parent route parameter

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:

  1. ProfilePageComponent fetches the profile ID in routing parameters and sends it to a ProfilePageService
  2. 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 ?

like image 316
Loheek Avatar asked Jan 31 '26 06:01

Loheek


1 Answers

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.

like image 107
Felix Lemke Avatar answered Feb 01 '26 21:02

Felix Lemke



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!