Thursday, March 7, 2019

How to wall off services behind lazy-loading in an Angular 7 application.

The trick I elude to here, in the name of maintainability is done by having routes for every item at the main menu system, beyond an innocuous and innocent static home page which is just a landing page with some text that never changes, like so:

{ path: 'foo', loadChildren: './modules/foo.module#FooModule' },

 
 

The above would go in the main routing module which supports the outermost God module for the application. Then there would be a modules folder somewhere with two different modules for each route in the menu system, one being the main module which would load the services for external dependencies and the other being its sister routing module which might look like so:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { FooComponent } from '../components/foo.component';
import { FooAuthenticatedComponent } from '../components/foo-authenticated.component';
import { FooUnauthorizedComponent } from '../components/foo-unauthorized.component';
import { FooGuard } from '../guards/foo.guard';
const routes: Routes = [
   { path: '', component: FooComponent },
   { path: 'authenticated', component: FooAuthenticatedComponent, canActivate: [FooGuard] },
   { path: 'unauthorized', component: FooUnauthorizedComponent }
];
@NgModule({
   imports: [RouterModule.forChild(routes)],
   exports: [RouterModule],
   providers: [FooGuard]
})
export class FooRoutingModule { }

 
 

FooComponent would just look like this, attempting a redirect to FooAuthenticatedComponent and instead redirecting to FooUnauthorizedComponent if the FooGuard determined that the user should not go forward.

import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
   selector: 'foo',
   template: 'Authenticating...'
})
export class FooComponent {
   constructor(router: Router) {
      router.navigate(['/foo','authenticated']);
   }
}

 
 

FooGuard could look like:

import { Injectable, Injector } from '@angular/core';
import { ActiveDirectoryContract } from '../contracts/active-directory.contract';
import { Router, CanActivate, ActivatedRouteSnapshot } from '@angular/router';
import { User } from '../models/user.model';
import { Role } from '../models/role.enum';
@Injectable()
export class FooGuard implements CanActivate {
   private activeDirectoryContract:ActiveDirectoryContract;
   private router: Router;
   
   constructor(public injector: Injector, public router: Router){
      this.activeDirectoryContract = injector.get(ActiveDirectoryContract);
      this.router = injector.get(Router);
   }
   
   canActivate(route: ActivatedRouteSnapshot): boolean {
      let user:User = this.activeDirectoryContract.GetUser(false);
      if (user.Role != Role.Yin && user.Role != Role.Yang) {
         this.router.navigate(['/foo','unauthorized']);
      }
      return true;
   }
}

No comments:

Post a Comment