Search code examples
angularroutesurl-routingangular-router

Routing to a specific route URL directly in angular4


Project Structure

The project structure of my project. I am following angulars guide for arranging your project in modules here. https://angular.io/guide/router#milestone-4-crisis-center-feature

app-routing.module.ts

const routes: Routes = [
  {
    path: 'portal',
    canActivate: [RuntimeEnvironmentService],
    loadChildren: 'app/portal/portal.module#PortalModule',
  },
  {
    path: '',
    canActivate: [RuntimeEnvironmentService],
    loadChildren: 'app/features/features.module#FeaturesModule',
  }

];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      preloadingStrategy: environment.preloadAllLazyLoadedModules
        ? PreloadAllModules
        : NoPreloading,
    }),
  ],
})
export class AppRoutingModule {}

If user navigates to http://localhost:4200 I want the user to be directed to FeaturesModule which works fine.

But when user navigates to http://localhost:4200/portal I want that user to be directed to the components in the PortalModule which does not work.

Snapshot of features-routing.module.ts

const routes: Routes = [
  {
    path: '',
    component: FeaturesComponent,
    children: [
      {
        path: 'map-page',
        component: MapPageComponent
      },
      {
        path: '',
        redirectTo: 'map-page',
        pathMatch: 'full'
      }
    ]
  }
];

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

Snapshot of portal-routing.module.ts

const routes: Routes = [
  {
    path: 'portal',
    component: PortalComponent,
    children: [
      {
        path: '',
        component: LoginComponent
      }
    ]

  }
];

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

app.component.html just has nothing but just one router-outlet tag

<router-outlet></router-outlet>

features.component.html has its own html and also one router-outlet tag to display the map component.

portal.component.html has this at the moment

<p>
  portal works! Why this is not displayed !!!
  <router-outlet></router-outlet>
</p>

Snapshot of AppModule

import { environment } from 'environments/environment';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CoreModule } from './core/core.module';
import { SharedModule } from './shared/shared.module';
import { PortalModule } from './portal/portal.module';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    CoreModule,
    SharedModule,
    PortalModule,
    AppRoutingModule
  ],
  providers: [
    // use hash location strategy or not based on env
    {
      provide: LocationStrategy,
      useClass: environment.hashLocationStrategy
        ? HashLocationStrategy
        : PathLocationStrategy,
    },
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

Snapshot of the features.module.ts

@NgModule({
  imports: [
            SharedModule,
            FeaturesRoutingModule,
            AgmCoreModule.forRoot({
              apiKey: 'AIzaSyAzGVaB4-VPQvIKlhcxz_uy2ft8uCPMZP4'
            })
  ],
  declarations: [
            FeaturesComponent,
            MapPageComponent,
  ],
  providers: [
            SkymeetService
  ]
})
export class FeaturesModule {}

Snapshot of the portal.module.ts

@NgModule({
  imports: [
    SharedModule,
    PortalRoutingModule
  ],
  declarations: [
    PortalComponent,
    LoginComponent
  ]
})
export class PortalModule { }

Since I have imported PortalModule in the AppModule I can see console.log in the ngOninit() of the PortalComponent class and LoginComponent class but the HTML does not get loaded. There is no error displayed. If I don't import PortalModule class then nothing is displayed. Any help is greatly appreciated.


Solution

  • Router merges all routes into one array once it loads children, so when it merges your forRoot configuration with forChild you get:

    const routes = [
        {
            path: 'portal',
            canActivate: [RuntimeEnvironmentService],
            children: {
                path: 'portal',
                component: PortalComponent,
                children: [
                    {
                        path: '',
                        component: LoginComponent
                    }
                ]
            }
    

    So to navigate to PortalComponent, the route should be:

    portal/portal
    

    If you want to use /portal only, you need to change forChild configuration to:

    const routes: Routes = [
      {
        path: '',
        component: PortalComponent,
        children: [
          {
            path: '',
            component: LoginComponent
          }
        ]