Search code examples
angularangular-routerangular-moduleangular-router-guards

Angular - Provide guards across different modules


Basically I have the following Angular modules at the moment:

  1. landing
  2. admin
  3. core
  4. shared

What I would like is to register a new guard called AuthenticationGuard within the shared module and provide it accross the different modules.

At the moment it only works, if I register the guard within the landing-module (which is the one I bootstrap) and neither if I register it in the admin.module or shared.module.

If I do that, I receive an error stating the following:

enter image description here

The registration of the guard is done via providers array of the corresponding modules.

My goal is to be able to use it across all modules.

There was no issue to inject a service from an the core within the admin module - so I assume there must be a difference between guards and services over all?

Currently some of the relevant files look like that (shortened for the sake of brevity):

landing.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { HomeComponent } from './home/home.component';
import { LandingRoutingModule } from './landing.routing.module';

import { SharedModule } from '../shared/shared.module';
import { CoreModule } from '../core/core.module';
import { SecurityModule } from '../security/security.module';
import { AdminModule } from '../admin/admin.module';

@NgModule({
  declarations: [
    HomeComponent
  ],
  imports: [
    SharedModule.forRoot(),
    CoreModule.forRoot(),
    SecurityModule,
    LandingRoutingModule
  ],
  providers: [],
  bootstrap: [HomeComponent]
})
export class AppModule { }

landing.routing.module

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

import { HomeComponent } from './home/home.component'
import { NotFoundComponent } from './../shared/components/not-found/not-found.component';

const appRoutes: Routes = [
  {
    path : '',
    redirectTo : '/login',
    pathMatch: 'full'
  },
  {
    path : 'admin',
    loadChildren: 'app/modules/admin/admin.module#AdminModule'
  },
  { 
    path: '**', 
    component: NotFoundComponent 
  }
];

@NgModule({
  declarations: [],
  imports: [
    HttpClientModule,
    RouterModule.forRoot(
      appRoutes,
      { enableTracing: true }
    )
  ],
  exports: [
    RouterModule
  ],
})

export class LandingRoutingModule { }

admin.module

import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedModule } from '../shared/shared.module';

import { AdminLandingComponent } from './admin-landing/admin- 
landing.component'
import { AdminChildComponent } from './admin-child/admin-child.component'
import { AdminRoutingModule } from './admin.routing.module';

@NgModule({
  declarations: [
    AdminLandingComponent,
    AdminChildComponent
  ],
  imports: [
    CommonModule,
    AdminRoutingModule
  ],
})
export class AdminModule { }

admin.routing.module

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

import { AdminLandingComponent } from './admin-landing/admin- 
landing.component';
import { AdminChildComponent } from './admin-child/admin-child.component';

import { AuthenticationGuard } from '../shared/guards/auth-guard.service'

const adminRoutes: Routes = [
    {
        path: '',
        component: AdminLandingComponent,
        canActivate: [AuthenticationGuard],
        children: [
            {
                path: '',
                children: [
                    { path: 'child', component: AdminChildComponent }
                ]
            }
        ]
    }
];

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

export class AdminRoutingModule { }

shared.module

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

import { NotFoundComponent } from './components/not-found/not- 
found.component'
import { AuthenticationGuard } from './guards/auth-guard.service';

@NgModule({
  declarations: [
    NotFoundComponent,  
  ],
  imports: [
    CommonModule
  ],
})

export class SharedModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: SharedModule,
      providers: [AuthenticationGuard]
    };
  }
}

auth-guard.service

import { Injectable }               from '@angular/core';
import {
    CanActivate, Router,
    ActivatedRouteSnapshot,
    RouterStateSnapshot,
    CanActivateChild,
    NavigationExtras,
    CanLoad,
    Route
}                                   from '@angular/router';
import { AuthenticationService }    from '../../core/services/authentication-service/authentication.service';

@Injectable()
export class AuthenticationGuard implements CanActivate, CanActivateChild, CanLoad {

    constructor(private authService: AuthenticationService, private router: Router) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        return true;
    }

    canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        return this.canActivate(route, state);
    }

    canLoad(route: Route): boolean {
        return true;
    }
}

Solution

  • You need to import the AuthenticationService in your module decorator in the providers array. That is what that error is indicating!

    Based on what you have here, I do not see AuthenticationService added as a provider in any of your modules. Unless it is in your app.modules.ts which isn't displayed here.