3

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 ?

1 Answer 1

7

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.