angularroutesangular2-routingangular2-router

In Angular, how I navigate directly to a path inside a lazy loaded module?


I would like to have two top level paths for logging in and registering.

I would prefer not having to do auth/log-in and auth/register.

However, the auth components are in a separate module, which is good because it shouldn't be loaded unless specifically requested.

export const routes: Route[] = [
  { path: 'log-in',   loadChildren: './auth-module/auth.module#AuthModule'},
  { path: 'register', loadChildren: './auth-module/auth.module#AuthModule'}
];

How can I specify when I am defining my routes that I want the log-in path to go to the log-in path inside the lazy loaded AuthModule, and the register path to go to the register path inside the lazy loaded module?


Solution

  • export const routes: Route[] = [
      { path: 'log-in',   loadChildren: './auth-module/auth.module#AuthModule'},
      { path: 'register', loadChildren: './auth-module/auth.module#AuthModule'}
    ];
    

    I will try to say it's not possible. Lazy loading modules loaded by redirects. This means:

    Doesn't matter for which route it navigated, if it's a lazy module, then it will try to find entry path. In your case two routes loading the same module, but also they reference to the same entry route path (path: '').

    If you really want to divide them, they should allocated in different modules.

    export const routes: Route[] = [
      { path: 'log-in',   loadChildren: './auth-module/someModule#someModule'},
      { path: 'register', loadChildren: './auth-module/auth.module#AuthModule'}
    ];
    

    some-module.routing.ts:

    {
        path: '',
        component: LoginComponent,
    
    },
    

    UPDATE 29.04.18. Simple solution with one more component

    Solution is to create additional component which acts as renderer of other components depending on the current url.

    app-routing.module:

    const appRoutes: Routes = [
     ...
    
      {
        path: 'admin',
        loadChildren: 'app/admin/admin.module#AdminModule',
    
      },
      {
        path: 'login',
        loadChildren: 'app/admin/admin.module#AdminModule',
    
      },
      {
        path: 'crisis-center',
        loadChildren: 'app/crisis-center/crisis-center.module#CrisisCenterModule',
        // data: { preload: true }
      },
      { path: '', redirectTo: '/superheroes', pathMatch: 'full' },
      { path: '**', component: PageNotFoundComponent }
    ];
    

    In admin.module create renderer component

    central.component.ts:

    ...
    
    @Component({
      selector: 'app-central',
      templateUrl: './central.component.html',
      styleUrls: ['./central.component.css']
    })
    export class CentralComponent implements OnInit {
    
      currentComponent: LoginComponent | AdminComponent;
    
      constructor(public router: Router, public activatedRoute: ActivatedRoute) { }
    
      ngOnInit() {
        if (this.router.url === '/login') {
          this.currentComponent = LoginComponent;
        } else {
          this.currentComponent = AdminComponent;
        }
      }
    }
    

    central.component.template:

    <ng-container *ngComponentOutlet="currentComponent"></ng-container>
    

    So, as you can see, central component will dynamically render component depending on url path.

    For rendering used declarative approach method with NgComponentOutlet

    More detail about imperative and declarative approach: https://stackoverflow.com/a/49840700/5677886

    StackBlitz Demo