How to implement Guard for components which are lazy loaded in Angular 16+

196 views Asked by At

I am trying to trying to implement Guards for lazy loaded components. I have tried canMatch and canActivate for which I am getting the error.

Cannot match any routes. URL Segment: 'admin/home/all-users/658044f87bfc4f8d999c9464' Error: NG04002: Cannot match any routes.

When I try canActivateChild. I am able to reach the page as needed but I do not see any indication that Guard is being activated.

My routing is as follows:

App-routing.module.ts

 const routes: Routes = [
  { path: 'register', component: RegisterComponent },
  { path: 'login', component: LoginComponent },
  {
    path: 'dashboard/:id',
    canActivate: [authGuard],
    component: DashboardComponent,
  },
  { path: 'view', canActivate: [authGuard], component: ChatviewComponent },
  {
    path: 'group/:id',
    canActivate: [authGuard],
    component: GroupChatComponent,
  },
  {
    path: 'publichats/:id',
    canActivate: [authGuard],
    component: PublicChatsComponent,
  },
  {
    path: 'announcement/:id',
    canActivate: [authGuard],
    component: AnnouncementsComponent,
  },
  {
    path: '',
    children: [
      {
        path: 'admin',
        loadChildren: () =>
          import('./Admin/admin.module').then((mod) => mod.AdminModule),
      },
    ],
  },
];

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

This is the Guard used here.

authgaurd.guard.ts

import { CanActivateFn, Router } from '@angular/router';

export const authGuard: CanActivateFn = (route, state) => {
  const routes:Router = new Router()
  const isAuth = localStorage.getItem("isAuthenticated");
  if (isAuth!==null){
    return true;
  }

  else{
    routes.navigate([''])
    return false;
  }

};

Theses are the routing of the child components:

admin-routing.module.ts

const routes: Routes = [
  {
    path:'header',
    component: HeaderBarComponent,
  },
  {
    path: 'login',
    component: AdminLoginComponent,
  },
  {
    path: 'dashboard/:id',
    component: DashComponent,
    canMatch:[authAdminGuard]
    // canActivate: [authAdminGuard]
  },

  {
    path: '',
    children: [
      {
        path: 'home',
        loadChildren: () =>
          import('./HomeComponents/home.module').then((mod) => mod.HomeModule),

      },
    ],
  },


];

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

home-routing.module.ts

const routes: Routes = [


  {
    path:'public-groups/:id',
    component:GroupsComponent,
    canMatch:[authAdminGuard]
  },
  {
    path:'all-users/:id',
    component:UsersComponent,
    canMatch:[authAdminGuard]
  },
  {
    path:'broadcast-channel/:id',
    component:BroadcastComponent,
    canMatch:[authAdminGuard]
  },
  {
    path:'user-profile/:id',
    component:UserProfileComponent,
    canMatch:[authAdminGuard]
  },
];

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

The guard that I plan to use is as bellow:

authguard.guard.ts

import { CanActivateFn, Router } from '@angular/router';

export const authAdminGuard: CanActivateFn = (route, state) => {
  const routes:Router = new Router()
  const isAuth = localStorage.getItem("isAdminAuthenticated");
  if (isAuth)
      return true;
  else{
    routes.navigate(['/admin/login'])
    return false;
  }

};

Can someone please explain what has gone wrong?

1

There are 1 answers

5
Oscar On BEST ANSWER

Try updating route variable for app-routing.module.ts and admin-routing.ts.

For app-routing.module.ts

 const routes: Routes = [
   //...
   {
     path: 'admin',
     loadChildren: () =>
     import('./Admin/admin.module').then((mod) => mod.AdminModule),
   },
   {
     path: '',
     redirectTo: 'admin',
     pathMatch: 'full'
   }
];

For admin-routing.ts

const routes: Routes = [
  //...
  {
    path: 'home',
    loadChildren: () =>
    import('./HomeComponents/home.module').then((mod) => mod.HomeModule),
  },
  {
    path: '',
    redirectTo: 'home',
    pathMatch: 'full'
  }

];

You have to inject router for your guards instead simply create it:

for authAdminGuard guard

import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';

export const authAdminGuard: CanActivateFn = (route, state) => {
  const router: Router = inject(Router);
  const isAuth = localStorage.getItem("isAdminAuthenticated");
  if (isAuth)
    return true;
  else {
    routes.navigate(['/admin/login'])
    return false;
  }

};

Same change authGuard. Also check if these guards has been well provided in app.module.

This should solve your issue.