angularangular-routingangular-module

How to load different modules based on the url with angular?


I am trying to create an angular application, with two modules. One for the user part and one for the admin part.

I would like to load the module only if needed. For example if the requested url is /my-account it would load the user module. But if it's something that starts with /admin it should load the admin module.

After that i don't know if it's possible but each module should load his own routing (like app-routing).

For now i am just trying to change the bootstraped component based on the url.

I tried this solution: https://stackoverflow.com/a/53014303/10270107 But for me it doesn't work i have an error, and like the comment said everything is still loaded.

In my code i have two modules, one named PublicModule and AdminModule. Each modules have a simple component that only show a text "Public" and "Admin". Both component use the same selector <app-root>

Here is my AdminModule:

@NgModule({
  imports: [],
  declarations: [AdminRootComponent],
  exports: [AdminRootComponent],
  providers: [],
  entryComponents: [],
})
export class AdminModule {}

Here is my PublicModule:

@NgModule({
  imports: [],
  declarations: [PublicRootComponent],
  exports: [PublicRootComponent],
  providers: [],
  entryComponents: [],
})
export class PublicModule {}

Then that's inside my app.module.ts that I want to dynamically load the bootstrap component. For now I'm only able to switch components by uncommenting the commented line in the bootstrap and commenting the other one.

@NgModule({
  imports: [BrowserModule, FormsModule, PublicModule, AdminModule],
  declarations: [],
  bootstrap: [
    PublicRootComponent,
    //AdminRootComponent
  ],
})
export class AppModule {}

Here is my two components, first public-root.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './public-root.component.html',
})
export class PublicRootComponent {
  public constructor() {}
}

Then admin-root.component

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './admin-root.component.html',
})
export class AdminRootComponent {
  public constructor() {}
}

In the template I only have a simple text Public or Admin, depending on which component it is.


Solution

  • This is call LazyLoading: in the app.module you need to load the module according to route like this:

    imports: [
      RouterModule.forRoot([
        {
          path: 'public',
          loadChildren: () => import('./public/public.module').then((m) => m.PublicModule),
        },
        {
          path: 'admin',
          loadChildren: () => import('./admin/admin.module').then((m) => m.AdminModule),
        },
      ]),
    ],
    

    That will load the modules base on route

    and inside the child modules you manage the route like this:

    RouterModule.forChild([
      {
        path: 'fff',
        component: YourComponent,
      },
    ]),
    

    Basically the different is that - in the parent module you need to use forRoot and in child modules you need to use forChild