Saturday 2 February 2019

Angular custom preloading strategy

Angular custom preloading strategy



To control when a lazy loaded module is downloaded onto the client machine, we use preloadingStrategy property. We discussed this in detail  of Angular 6 tutorial.

Let us say in our Angular project, we have 2 lazy loaded modules 
  • EmployeeModule
  • AdminModule
If we set, preloadingStrategy property to PreloadAllModules, then both the lazy loaded modules will be preloaded in the background. 

RouterModule.forRoot(appRoutes, {preloadingStrategy: PreloadAllModules})

On the other hand, if we set preloadingStrategy property to NoPreloading, then none of the lazy loaded modules will be preloaded. 

RouterModule.forRoot(appRoutes, {preloadingStrategy: NoPreloading})

So with the following 2 built-in preloadingStrategy options, we can either preload, all lazy loaded modules or none of them. 
  • PreloadAllModules
  • NoPreloading
But, what if we want to preload some of the modules and not the other. In our case, let's say we want to preload EmployeeModule, but not the AdminModule. This is when, we create our own Custom Preloading Strategy. 

Steps for creating Custom Preloading Strategy in Angular

Step 1 : To create a Custom Preloading Strategy, create a service that implements Angular's built-in PreloadingStrategy abstract class

To generate the service, use the following Angular CLI command 
ng g s CustomPreloading

This command generates a file with name custom-preloading.service.ts. Modify the code in that file as shown below. 

import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, of } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
// Since we are creating a Custom Preloading Strategy, this service
// class must implement PreloadingStrategy abstract class
export class CustomPreloadingService implements PreloadingStrategy {

  constructor() { }

  // PreloadingStrategy abstract class has the following preload()
  // abstract method for which we need to provide implementation
  preload(route: Route, fn: () => Observable<any>): Observable<any> {
    // If data property exists on the route of the lazy loaded module
    // and if that data property also has preload property set to
    // true, then return the fn() which preloads the module
    if (route.data && route.data['preload']) {
      return fn();
    // If data property does not exist or preload property is set to
    // false, then return Observable of null, so the module is not
    // preloaded in the background
    } else {
      return of(null);
    }
  }
}

Step 2 : Import CustomPreloadingService and set it as the Preloading Strategy 

In app-routing.module.ts, import CustomPreloadingService 

import CustomPreloadingService from './custom-preloading.service';

Set CustomPreloadingService as the Preloading Strategy 

RouterModule.forRoot(appRoutes, {
  preloadingStrategy: CustomPreloadingService
})

Modify the 'employees' route, and set preload property to true or false. Set it to true if you want the EmployeeModule to be preloaded else false. 

const appRoutes: Routes = [
  { path: 'home', component: HomeComponent },
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  {
    path: 'employees',
    // set the preload property to true, using the route data property
    // If you do not want the module to be preloaded set it to false
    data: { preload: true },
    loadChildren: './employee/employee.module#EmployeeModule'
  },
  { path: '**', component: PageNotFoundComponent }
];

No comments:

Post a Comment