Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular navigate directly to lazy loaded module child route

I have an Angular module lazy loaded called example.module. In example.module I have two different components called a.component and b.component and a bunch of different sub components both a and b use.

What I would like is that when the module is lazy loaded from the router I can route directly to either one of those two components based on which route the user selected from the parent routing.

The only work around I can think of is making two entirely separate modules each of which is lazy loaded independently with the common code being in a third shared module imported by the two. That seems like a lot more templated code and files I need to produce across my entire application rather then there being some way I can signal to a lazyloaded component to load one of the routes programmatically.

        RouterModule.forChild(
        [
          {
            path: "",
            redirectTo: "component-a" // How do I go to A or B?
          },
          {
            path: "component-a",
            component: ComponentA
          },
          {
            path: "component-b",
            component: ComponentB
          },
        ]

Thanks for your assistance and knowledge on the topic!

Edit - As requested root routing.

const appRoutes: Routes = [
  {
    path: "example",
    loadChildren: "./example.module#ExampleModule",
  },
];

@NgModule({
  imports: [
      RouterModule.forRoot(appRoutes)
  ],
  exports: [
      RouterModule
  ]
})
export class AppRoutingModule { }

Plunk - https://embed.plnkr.co/uiLFu0EBZ00F8sLH836w/

like image 805
user3333134 Avatar asked Oct 18 '22 05:10

user3333134


2 Answers

When working with lazy loaded modules you should treat them as eagerly loaded modules and the routes configuration you specify in the .forChild(routes) is merged into the single application wide configuration.

So in your particular case you define in the forRoot:

export const routes: Routes = [
  { path: 'crisis-a', loadChildren: 'app/crisis/crisis.module#CrisisModule' },
  { path: 'crisis-b', loadChildren: 'app/crisis/crisis.module#CrisisModule' }
];

and in the .forChild()

const routes: Routes = [
  { path: 'crisis-a',    component: CrisisListComponentA },
  { path: 'crisis-b',    component: CrisisListComponentB },
];

So once merged you will have the following configuration:

export const routes: Routes = [
  { 
    path: 'crisis-a', 
    children: [
        { path: 'crisis-a',    component: CrisisListComponentA },
        { path: 'crisis-b',    component: CrisisListComponentB }
    ]
  { 
    path: 'crisis-b', 
    children: [
        { path: 'crisis-a',    component: CrisisListComponentA },
        { path: 'crisis-b',    component: CrisisListComponentB }
    ]
  }
];

Hence if you want to navigate to CrisisListComponentB with /crisis-b you have to specify full URL

/crisis-b/crisis-b
like image 60
Max Koretskyi Avatar answered Oct 20 '22 23:10

Max Koretskyi


I would make a canActivate guard to route them appropriately once the module is resolved.

Update the routes to be:

RouterModule.forChild(
[
  {
    path: "",
    canActivate: [RootRouteGuard]
  },
  {
    path: "component-a",
    component: ComponentA
  },
  {
    path: "component-b",
    component: ComponentB
  },
]

And then the guard would look something like this:

@Injectable()
export class RootRouteGuard implements CanActivate {

  constructor(private router: Router) {}

  public canActivate(route: ActivatedRouteSnapshot) {
    if (/* Logic */) {
      this.router.navigateByUrl('component-a');
    } else {
      this.router.navigateByUrl('component-b');
    }
  }
}
like image 25
Teddy Sterne Avatar answered Oct 20 '22 23:10

Teddy Sterne