10

I have multiple components in one module. I want to show the components based on routing path. for http://localhost:4200/account I want to show account component. for http://localhost:4200/setting I want to show settings component ..etc

app.routing.module.ts

{
    path: 'account',
    loadChildren: './modules/settings/settings.module#SettingsModule',
},
{
    path: 'settings',
    loadChildren:'./modules/settings/settings.module#SettingsModule', 
},

settings.routing.module.ts

export const routes: Routes = [
    {
        path: 'account',
        component: accountComponent
    },
    {
        path: 'account/edit',
        component: accountEditComponent
    },
    {
        path: 'settings',
        component: settingsComponent
    },
    {
        path: 'settings/edit',
        component: settingsEditComponent
    }
];

what changes I do in settings.routing.module.ts to show those components.

1
  • 2
    There is no sense in what you're trying to do. Why are your not making each route as a different lazy loaded module? Commented Jul 18, 2019 at 8:48

5 Answers 5

13

If you really want to do this you can use UrlMatcher to find the correct component.

SIDE NOTE:I wouldn't recommend you to do this. instead go with my other answer. I think it's a better approach. BUT of-course it's your decision.

Simple demo

app.routing.module.ts (not changed)

{
    path: 'settings/account',
    loadChildren: './modules/settings/settings.module#SettingsModule',
},
{
    path: 'settings',
    loadChildren:'./modules/settings/settings.module#SettingsModule', 
}

settings.routing.module.ts

export function isAccount(url: UrlSegment[], group: UrlSegmentGroup) {
  return group.segments.length === 1 && group.segments[0].path.endsWith('account') ? ({consumed: url}) : null;
}

export function isSettings(url: UrlSegment[], group: UrlSegmentGroup) {
  return group.segments.length === 1 && group.segments[0].path.endsWith('settings') ? ({consumed: url}) : null;
}

export const routes: Routes = [
    {
        path: 'account',
        component: accountComponent,
        matcher: isAccount
    },
    {
        path: 'account/edit',
        component: accountEditComponent
    },
    {
        path: 'settings',
        component: settingsComponent,
        matcher: isSettings
    },
    {
        path: 'settings/edit',
        component: settingsEditComponent
    }
];

Result is exactly what you're looking for:

http://localhost:4200/settings will show settings component.

http://localhost:4200/account will show account component.

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

2 Comments

This should be build into Angular without this hack... shorter urls with lazy-loading is better!
put the functions to return UrlMatchResult. More clear.
3

One way is to have settings as the default path (component) for this module, and all other components as a child route.

Simple DEMO

app.routing.module.ts

{
    path: 'settings/account',
    loadChildren: './modules/settings/settings.module#SettingsModule',
},
{
    path: 'settings',
    loadChildren:'./modules/settings/settings.module#SettingsModule', 
},

settings.routing.module.ts

export const routes: Routes = [
    {
        path: '',
        component: settingsComponent
    },
    {
        path: 'edit',
        component: settingsEditComponent
    },
    {
        path: 'account',
        component: accountComponent
    },
    {
        path: 'account/edit',
        component: accountEditComponent
    }
];

http://localhost:4200/setting will show settings component.

http://localhost:4200/settings/account will show account component.

..etc

Comments

1

You can do something like this

settings-routing.module.ts

const routes: Routes = [
    {
        path: '',
        component: PubliclistsComponent,
        children: [
          {path: '', redirectTo: 'all', pathMatch: 'full'},
          {path: 'all', component: ChallengelistComponent},
          {path: 'me', component: ChallengelistComponent}
        ]
    }
];

const settingsRoutes: Routes = [
    {
        path: '',
        component: SettingsComponent,
        children: [
          {path: '', redirectTo: 'participants', pathMatch: 'full'},
          {path: 'bleh', component: TeamlistComponent},
          {path: 'bleh-bleh', component: TeamlistComponent}
        ]
    },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class AccountsRoutingModule { }


@NgModule({
  imports: [RouterModule.forChild(settingsRoutes)],
  exports: [RouterModule]
})
export class SettingsRoutingModule { }

settings.module.ts

@NgModule({
  declarations: [],
  imports: [
    ...
  ]
})
export class AccountModule { }


@NgModule({
  declarations: [],
  imports: [
    ...
  ]
})
export class SettingsModule { }

app-routing.ts

{
    path: 'account',
    loadChildren: './modules/settings/settings.module#AccountsModule',
},
{
    path: 'settings',
    loadChildren:'./modules/settings/settings.module#SettingsModule', 
},

Comments

0

Adding to benshabatnoam's Answer above, you could create a universal matcher function like so in your module:

// load components from root path
export function isPath(url: UrlSegment[], group: UrlSegmentGroup, route: Route) {
  let r = '';
  for (const p of group.segments) {
    if (p !== group.segments[0]) {
      r += '/';
    }
    r += p.path;
  }
  return r === route.data!.path
    ? ({ consumed: url })
    : null;
}

const routes: Routes = [
  { component: SettingsComponent, matcher: isPath, data: { 'path': 'settings' } },
  { component: AccountComponent, matcher: isPath, data: { 'path': 'account' } },
{ component: AccountComponent, matcher: isPath, data: { 'path': 'full/path' } }
];

Comments

0

the solution is to create two lazy modules that share a third non-lazy module.

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.