DEV Community

Cover image for Authentication preload strategy
Marko Berger
Marko Berger

Posted on


Authentication preload strategy

I have decided to write my own custom authentication preload strategy. I got an idea from John Papa and his preload strategy series of articles. I truly recommend you read this series of articles on this subject. So what are custom preload strategies?

It’s a way you can tell your Angular application how to bundle your javascript code in a predefined way of your choosing.

For this let’s say we have the authentication service that will reload what modules are going to be preloaded based on the user role. I’m not going to deeper on how or where you will store your strategy. Because it is a philosophical question :-).
I'm going to set up my preload strategies in the environment variable. (This is just one way of doing this).

strategies: new Map([
    ['default', ['module1']],
    ['admin', ['module1', 'module2', 'module3']],
    ['user', ['module1', 'module2']]

Our router setup.

const routes: Routes = [
  {path: '', redirectTo: '/home', pathMatch: 'full'}, //not important
  {path: 'home', component: HomeComponent}, //not important
   path: 'module1', 
   loadChildren: '../app/module1/module1.module#Module1Module', 
   data: {preload: true}
   path: 'module2', 
   loadChildren: '../app/module2/module2.module#Module2Module', 
   data: {preload: true}
   path: 'module3', 
   loadChildren: '../app/module3/module3.module#Module3Module', 
   data: {preload: true}
  imports: [RouterModule.forRoot(routes, {preloadingStrategy: RolePreloadService})],
  exports: [RouterModule]

Let's create what we need in our auth service

export class OnDemandRolePreloadOptions {
  constructor(public routePath: string, public preload = true) {}
  providedIn: 'root'
export class AuthServiceService {

  constructor() { }

    const rolePaths: OnDemandRolePreloadOptions[] = this.generatePaths()
    return from(rolePaths);
    return environment.strategies.get('default') //default preload
    .map( mod => new OnDemandRolePreloadOptions(mod, true));

This is just to serve this example
In a nutshell. We need to return our OnDemandRolePreloadOptions class of a default strategy as observable.

Now that we got our strategy. Let's do some magic in role-preload.service.ts

export class RolePreloadService implements PreloadingStrategy {
  userRole$: Observable<OnDemandRolePreloadOptions>;

  constructor(private authService: AuthServiceService) { 
    this.userRole$ = this.authService.getUserRolePreloadOption();

  preload(route: Route, load: () => Observable<any>): Observable<any> {

    return this.userRole$.pipe(
      mergeMap(role => {
        const shouldPreload = this.preloadCheck(route, role);
        return shouldPreload ? load() : EMPTY;

  preloadCheck(route: Route, preloadRoleOptions: OnDemandRolePreloadOptions){
    return ( &&['preload'] && 
      [route.path, '*'].includes(preloadRoleOptions.routePath) &&


So preloadCheck() method is what is doing the heavy lifting here. It checks if the lazy load route is predefined for preload, does it exists in router and preloadRoleOptions. If so it will load our preload strategy based on authentication. If you log in with admin account it will load preload admin javascript bundle.


Top comments (0)

An Animated Guide to Node.js Event Loop

Node.js doesn’t stop from running other operations because of Libuv, a C++ library responsible for the event loop and asynchronously handling tasks such as network requests, DNS resolution, file system operations, data encryption, etc.

What happens under the hood when Node.js works on tasks such as database queries? We will explore it by following this piece of code step by step.