This post describes how to implement lazy or dynamic component loading with angular, based on an Angular 10 demo implementation.

In Angular applications, it is sometimes necessary to load components or services dynamically/lazily and asynchronously at runtime. Just think of loading captcha, promotion, or advertisement components.
Manual component loading with Angular is achieved very easily once you have seen an example implementation, and that’s what I provide.

Assume an existing Angular application or at least a component (AppComponent) needs to be extended by an existing component (DynamicComponent), which should be loaded lazy, async at runtime.

1. Add an HTML-Container

Start the implementation by adding an HTML-Container.

...  
<div>
  <ng-container #dynamicContainer></ng-container>
</div>
...

And create a container reference to the associated Angular component.

export class AppComponent {
 
  @ViewChild('dynamicContainer', {read: ViewContainerRef})
  dynamicContainer: ViewContainerRef;
  
  ...
}

2. Lazy Load Angular Component

The ViewContainterRef provides a method called createComponent() that uses a ComponentFactory to create and inject a new component.
A ComponentFactory of a given type can be retrieved using the Angular ComponentFactoryResolver.

Do not forget to store the reference of the new component created, which is needed, for example, to manually destroy the component.

import {Component, ComponentFactoryResolver, ComponentRef, Injector, ViewChild, ViewContainerRef} from '@angular/core';
...
export class AppComponent {
  
  @ViewChild('dynamicContainer', {read: ViewContainerRef})
  dynamicContainer: ViewContainerRef;

  private _dynamicInstance: ComponentRef<DynamicComponent>;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) { }

  async loadComponentAsync() {
    const {DynamicComponent} = 
      await import('./components/dynamic/dynamic.component');
    
    // create component factory for DynamicComponent
    const dynamicComponentFactory = 
      this.componentFactoryResolver.resolveComponentFactory(DynamicComponent);
    
    // create and inject component into dynamicContainer
    this._dynamicInstance = 
      this.dynamicContainer.createComponent(dynamicComponentFactory, null);
  }

}

3. Destroy Lazy Loaded Component

The dynamically and manually created component can be destroyed using the stored component reference.

this._dynamicInstance.destroy();

4. Lazy Load Angular Service

Besides the lazy-loaded component, you will need to inject and use some service implementations inside our component. In the case of lazy-loaded components, you have to inject these services dynamically as well.

To archive that, Angular provides an Injector, which provides the implementation to get some services loaded lazily and dynamically at runtime.

import {Component, Injector} from '@angular/core';
import {DynamicService} from './services/dynamic.service';
...
export class AppComponent {
  
  private _lazyLoadedService: DynamicService;

  constructor(private injector: Injector) {
  }

  lazyLoadService() {
    this._lazyLoadedService = this.injector.get(DynamicService);
  } 


}

Categories: Engineering

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *