Module child route is ignored when using '**' in main application router for redirects

317 views Asked by At

I have tried to create a module with its own routes. The route is being ignored and redirecting to the page not found component which is in the main application routes. When I remove the following code - { path: '**', component: PageNotFoundPage } - from the main application routes the module route works. However now I cannot use the previous code to handle my 404 redirects. Does anyone know why this happens and how to fix it?

Main Application Module:

// Application Dependencies
import { NgModule, ApplicationRef } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { FormsModule } from '@angular/forms';

// Application Pages
/* Public Pages */
import { LandingPage } from './pages/public/landing.page';
import { EmailLoginPage } from './pages/public/email-login.page';
import { LinkedinLoginPage } from './pages/public/linkedin-login.page';
import { PageNotFoundPage } from './pages/public/page-not-found.page';
/* Private Parent Page */
import { DashboardComponent } from './pages/authenticated/dashboard.component';
/* Private Pages */
import { DevicesPage } from './pages/authenticated/devices.page';
import { DeviceDetailsPage } from './pages/authenticated/device-details.page';

import { GroupsPage } from './pages/authenticated/groups.page';
import { GroupDetailsPage } from './pages/authenticated/group-details.page';
import { GroupScorePage } from './pages/authenticated/group-score.page';
import { GroupDevicesPage } from './pages/authenticated/group-devices.page';
import { GroupMembersPage } from './pages/authenticated/group-members.page';
import { GroupInviteMemberPage } from './pages/authenticated/group-invite-member.page';

import { SitesPage } from './pages/authenticated/sites.page';
import { SiteDetailsPage } from './pages/authenticated/site-details.page';
import { SiteScorePage } from './pages/authenticated/site-score.page';
import { SiteDevicesPage } from './pages/authenticated/site-devices.page';
import { SiteTenantsPage } from './pages/authenticated/site-tenants.page';
import { SiteInviteTenantPage } from './pages/authenticated/site-invite-tenant.page';

import { CyberScorePage } from './pages/authenticated/cyber-score.page.';
import { ProfilePage } from './pages/authenticated/profile.page';

// Application Modules
import { RoutingModule } from './app.routing';
import { AuthModule } from './modules/auth/auth.module';

/* ======== testing ======== */
import { TestingModule } from './modules/testing/testing.module';
/* ======== testing ======== */

// Application Components
import { AppComponent } from './app.component';
import { ToolbarComponent } from './components/site/toolbar/toolbar.component';
import { NotificationsComponent } from './components/site/notifications/notifications.component';
/* Page Components */
import { LandingComponent } from './components/pages/landing/landing.component';
import { EmailLoginComponent } from './components/pages/email-login/email-login.component';
import { LinkedinLoginComponent } from './components/pages/linkedin-login/linkedin-auth.component';
import { PageNotFoundComponent } from './components/pages/page-not-found/page-not-found.component';

import { DevicesComponent } from './components/pages/devices/devices.component';
import { DeviceDetailsComponent } from './components/pages/devices/device-details.component';

import { GroupsComponent } from './components/pages/groups/groups.component';
import { GroupDetailsComponent } from './components/pages/groups/group-details.component';
import { GroupScoreComponent } from './components/pages/groups/group-score.component';
import { GroupDevicesComponent } from './components/pages/groups/group-devices.component';
import { GroupMembersComponent } from './components/pages/groups/group-members.component';
import { GroupInviteMemberComponent } from './components/pages/groups/group-invite-member.component';

import { SitesComponent } from './components/pages/sites/sites.component';
import { SiteScoreComponent } from './components/pages/sites/site-score.component';
import { SiteDetailsComponent } from './components/pages/sites/site-details.component';
import { SiteDevicesComponent } from './components/pages/sites/site-devices.component';
import { SiteTenantsComponent } from './components/pages/sites/site-tenants.component';
import { SiteInviteTenantComponent } from './components/pages/sites/site-invite-tenant.component';

import { CyberScoreComponent } from './components/pages/cyber-score/cyber-score.component';
import { ProfileComponent } from './components/pages/profile/profile.component';

// Application Services
import { Env } from '../_env';
import { removeNgStyles, createNewHosts } from '@angularclass/hmr';
import { HttpHeaders } from './shared/services/httpHeaders';
import { Notifications } from './components/site/notifications/notifications.service';

import { InviteTenantHttp } from './components/pages/sites/site-invite-tenant-http.service';
import { GroupsHttp } from './components/pages/groups/groups-http.service';

@NgModule({
  imports: [
    BrowserModule,
    HttpModule,
    FormsModule,
    RoutingModule,
    // Custom Modules
    AuthModule,
    TestingModule
  ],
  declarations: [
    AppComponent,
    ToolbarComponent,
    NotificationsComponent,
    // Public Pages
    LandingPage,
    LandingComponent,
    EmailLoginPage,
    EmailLoginComponent,
    LinkedinLoginPage,
    LinkedinLoginComponent,
    PageNotFoundPage,
    PageNotFoundComponent,
    // Private Pages
    DashboardComponent,
    ProfilePage,
    ProfileComponent,
    DevicesPage,
    DevicesComponent,
    DeviceDetailsPage,
    DeviceDetailsComponent,
    /* Groups */
    GroupsPage,
    GroupsComponent,
    GroupDetailsPage,
    GroupDetailsComponent,
    GroupScorePage,
    GroupScoreComponent,
    GroupDevicesPage,
    GroupDevicesComponent,
    GroupMembersPage,
    GroupMembersComponent,
    GroupInviteMemberPage,
    GroupInviteMemberComponent,
    /* Sites */
    SitesPage,
    SitesComponent,
    SiteDetailsPage,
    SiteDetailsComponent,
    SiteScorePage,
    SiteScoreComponent,
    SiteDevicesPage,
    SiteDevicesComponent,
    SiteTenantsPage,
    SiteTenantsComponent,
    SiteInviteTenantPage,

    SiteInviteTenantComponent,

    CyberScorePage,
    CyberScoreComponent
  ],
  providers: [
    Env,
    HttpHeaders,
    InviteTenantHttp,
    GroupsHttp,
    Notifications
  ],
  bootstrap: [
    AppComponent
  ]
})

export class AppModule {

  constructor(public appRef: ApplicationRef) {}

  hmrOnInit(store) {
    console.log('HMR store', store);
  }

  hmrOnDestroy(store) {
    let cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement);
    // recreate elements
    store.disposeOldHosts = createNewHosts(cmpLocation);
    // remove styles
    removeNgStyles();
  }

  hmrAfterDestroy(store) {
    // display new elements
    store.disposeOldHosts();
    delete store.disposeOldHosts;
  }
}

Main Application Routes:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

// Application Pages;
/* Public Pages */
import { LandingPage } from './pages/public/landing.page';
import { EmailLoginPage } from './pages/public/email-login.page';
import { LinkedinLoginPage } from './pages/public/linkedin-login.page';
import { PageNotFoundPage } from './pages/public/page-not-found.page';
/* Private Parent Page */
import { DashboardComponent } from './pages/authenticated/dashboard.component';
/* Private Pages */
import { DevicesPage } from './pages/authenticated/devices.page';
import { DeviceDetailsPage } from './pages/authenticated/device-details.page';

import { GroupsPage } from './pages/authenticated/groups.page';
import { GroupDetailsPage } from './pages/authenticated/group-details.page';
import { GroupScorePage } from './pages/authenticated/group-score.page';
import { GroupDevicesPage } from './pages/authenticated/group-devices.page';
import { GroupMembersPage } from './pages/authenticated/group-members.page';
import { GroupInviteMemberPage } from './pages/authenticated/group-invite-member.page';

import { SitesPage } from './pages/authenticated/sites.page';
import { SiteDetailsPage } from './pages/authenticated/site-details.page';
import { SiteScorePage } from './pages/authenticated/site-score.page';
import { SiteDevicesPage } from './pages/authenticated/site-devices.page';
import { SiteTenantsPage } from './pages/authenticated/site-tenants.page';
import { SiteInviteTenantPage } from './pages/authenticated/site-invite-tenant.page';

import { ProfilePage } from './pages/authenticated/profile.page';
import { CyberScorePage } from './pages/authenticated/cyber-score.page.';

// Services
import { AuthGuard } from './modules/auth/auth-guard.service';

const routes: Routes = [
  { path: 'landing', component: LandingPage },
  { path: 'email-login', component: EmailLoginPage },
  { path: 'linkedin-login', component: LinkedinLoginPage },
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [AuthGuard],
    children: [
      { path: 'devices', component: DevicesPage },
      { path: 'device/:id', component: DeviceDetailsPage },

      { path: 'groups', component: GroupsPage },
      { path: 'group/:id', component: GroupDetailsPage },
      { path: 'group-score', component: GroupScorePage },
      { path: 'group-devices', component: GroupDevicesPage },
      { path: 'group-members', component: GroupMembersPage },
      { path: 'group-invite-member', component: GroupInviteMemberPage },

      { path: 'sites', component: SitesPage },
      { path: 'site/:id', component: SiteDetailsPage },
      { path: 'site-score', component: SiteScorePage },
      { path: 'site-devices', component: SiteDevicesPage },
      { path: 'site-tenants', component: SiteTenantsPage },
      { path: 'site-invite-tenant', component: SiteInviteTenantPage },

      { path: 'profile', component: ProfilePage },
      { path: 'cyber-score', component: CyberScorePage },
      { path: '', component: DevicesPage }
    ]
  },
  {
    path: '',
    redirectTo: '/landing',
    pathMatch: 'full'
  },
  { path: '**', component: PageNotFoundPage }
];

@NgModule({
  imports: [ RouterModule.forRoot(routes) ],
  exports: [ RouterModule ]
})

export class RoutingModule {}

Testing Module .module.ts file:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

// Components:
import { TestingComponent } from './testing.component';

// Modules:
import { TestingRoutingModule } from './testing-routing.module';

// Services:

@NgModule({
  imports: [
    CommonModule,
    TestingRoutingModule
  ],
  declarations: [
    TestingComponent
  ],
  providers: [

  ]
})

export class TestingModule {}

Testing Module Routes:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { TestingComponent } from './testing.component';

const testingRoutes: Routes = [
  { path: 'test-route',  component: TestingComponent }
];

@NgModule({
  imports: [
    RouterModule.forChild(testingRoutes)
  ],
  exports: [
    RouterModule
  ]
})

export class TestingRoutingModule {}
2

There are 2 answers

0
Paul A. Trzyna On BEST ANSWER

When using the new router place child module routes before the root router. This should resolve your problem.

0
Aaron On

I found out the problem was due to the order of my module imports. I changed the module order as follows and the problem has been fixed:

// Custom Module
AuthModule,
TestingModule,
// Routing
RoutingModule