angularangular8angular-routingangular-routerlinkngx-admin

Angular 8 Child Routes not working from component


I have a strange issue, I've cloned ngx-admin and trying to use the theme as base theme.

I've created Layout Components with Modules with Routing enabled. Created routes and connected components but the problem is routes are working fine if I open them from link directly. But when I try to use router.navigate to redirect, the routes are not working.

below are my files

app-routing.module.ts

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

import { DashboardLayoutComponent } from './layouts/dashboard-layout/dashboard-layout.component';
import { AuthenticationLayoutComponent } from './layouts/authentication-layout/authentication-layout.component';

const routes = [
  {
    path: '',
    redirectTo: 'app',
    pathMatch: 'full',
  },
  {
    path: '',
    component: DashboardLayoutComponent,
    children: [
      {
        path: 'app',
        loadChildren: () => import('./layouts/dashboard-layout/dashboard-layout.module').then(m => m.DashboardLayoutModule)
      }
    ]
  },
  {
    path: '',
    component: AuthenticationLayoutComponent,
    children: [
      {
        path: 'auth',
        loadChildren: () => import('./layouts/authentication-layout/authentication-layout.module').then(m => m.AuthenticationLayoutModule)
      }
    ]
  },
  {
    path: '**',
    redirectTo: 'app'
  }
];

export const AppRoutingModule : Routes = routes;

app.module.ts

@NgModule({
  declarations: [
    AppComponent,
    DashboardLayoutComponent,
    AuthenticationLayoutComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    HttpClientModule,
    RouterModule.forRoot(AppRoutingModule),
    CookieModule.forRoot(),
    ThemeModule.forRoot(),
    NbSidebarModule.forRoot(),
    NbMenuModule.forRoot(),
    NbWindowModule.forRoot(),
    NbToastrModule.forRoot(),
    CoreModule.forRoot(),
    FormsModule,
    ReactiveFormsModule
  ],
  providers: [AuthGuard, AuthService],
  bootstrap: [AppComponent],
})
export class AppModule {
}

auth-layout.routing.ts

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

import { LoginComponent } from '../../pages/auth/login/login.component';
import { ForgotComponent } from '../../pages/auth/forgot/forgot.component';
import { VerifyComponent } from '../../pages/auth/verify/verify.component';

export const AuthenticationLayoutRoutingModule : Routes = [
  { path: '', redirectTo: 'login', pathMatch: 'full' },
  { path: 'login', component: LoginComponent },
  { path: 'forgot', component: ForgotComponent },
  { path: 'verify/invite/:_hash', component: VerifyComponent},
  { path: '**', redirectTo: 'login' }
]

auth-layout.module.ts

@NgModule({
  declarations: [
    LoginComponent,
    ForgotComponent,
    VerifyComponent
  ],
  imports: [
    CommonModule,
    RouterModule.forChild(AuthenticationLayoutRoutingModule),
    ThemeModule,
    NbAlertModule,
    FormsModule,
    ReactiveFormsModule,
    NbPopoverModule,
    NbCardModule,
    NbIconModule
  ],
})
export class AuthenticationLayoutModule { }

Im trying to navigate from Verify component to login component, Below is the code

constructor(private router: Router, private activatedRoute: ActivatedRoute, private authService: AuthService, private toastrService: NbToastrService) {}

  ngOnInit() {
    this.router.navigate['/auth/login'];
  }

But if I use below code, It will redirect properly

<a [routerLink]="['/auth/login']">Click to redirect</a>

Please tell me if I'm doing something wrong.


Solution

  • You're not calling router.navigate correctly. It is a function, and should be called like one:

    ngOnInit() {
      this.router.navigate(['/auth/login']);
    }
    

    Router module patterns

    In an unrelated issue, your routing modules are declared in a confusing way. What you're naming as modules aren't really modules.

    The typical patterns would either be:

    app.module.ts

    const appRoutes: Routes = [
      // ... routes here
    ];
    
    @NgModule({
      imports: [
        RouterModule.forRoot(appRoutes)
      ]
    })
    export class AppModule { }
    

    OR

    app-routing.module.ts

    const appRoutes: Routes = [
      // ... routes here
    ];
    
    @NgModule({
      imports: [
        RouterModule.forRoot(appRoutes)
      ],
      export: [RouterModule]
    })
    export class AppRoutingModule { }
    

    app.module.ts

    @NgModule({
      imports: [
        AppRoutingModule
      ]
    })
    export class AppModule { }
    

    Sticking to common conventions helps when it comes to reading new code (or your own old code) - you can recognise common patterns without having to mentally parse unfamiliar ones.