Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
April 21, 2023 04:53 am GMT

How to Lazy and Dynamically Load a Component in Angular

There are three ways you can use a component in an Angular app.

  • Loading on route change
  • Using as a child component
  • Dynamically loading on demand

However, this article focuses on loading a component dynamically and lazily. The main advantage of lazily loading a component is reducing the initial bundle size and only downloading the component in the browser when required.

Let us say that you have a component called GreetComponent, as shown in the next code block,

import { Component, EventEmitter, Input, Output } from '@angular/core';import { CommonModule } from '@angular/common';const template = ` <h2>{{message}} </h2> <button (click)='sendMessage()'>Send Message </button>`@Component({ selector: 'app-greet', standalone: true, imports: [CommonModule], template: template})export class GreetComponent { @Input({ required: true }) message?: string; @Output() messageEvent = new EventEmitter<boolean>(); sendMessage(): void { this.messageEvent.emit(true); }} 

The GreetComponent has an @Input decorated property and an @Output() decorated EvenEmmiter. The FooComponent uses it as a child component, as shown in the following code block.

const template = ` <app-greet [message]='message' (messageEvent)='sendMessage($event)'></app-greet>`@Component({ selector: 'app-foo', standalone: true, imports: [CommonModule, GreetComponent], template : template})export class FooComponent { message = "data from parent" sendMessage(m:boolean){ console.log(m); }}

A couple of points worth noticing here are,

  • GreetComponent is part of the imports array.
  • GreetComponent is used on the template.

Due to the above two points, whenever Angular compiles FooComponent, it also includes GreetComponent, increasing the size of the bundle containing the FooComponent.


*One main advantage of loading a component dynamically (lazily) is that it reduces the bundle size because it only gets downloaded in the browser when required. *


Let us say that, GreetComponent should be loaded dynamically and lazily with the click of a button in the FooComponent. For that,

  • Add a button
  • Remove from the template of FooComponent
  • Remove GreetComponent from the imports array. [Important]
const template = ` <button (click)='loadComponent()'>Load Greet Component </button>`@Component({ selector: 'app-foo', standalone: true, imports: [CommonModule], template: template})export class FooComponent { message = "data from parent" greetcomp: any;

To dynamically load the component, inject the ViewContainerRef using the inject function or the constructor injection.

vcr = inject(ViewContainerRef);

After that, import the file that contains GreetComponent using the import statement. The import statement is used in JavaScript to load a file dynamically.

const { GreetComponent } = await import('../greet/greet.component');

After importing the file, use the CreateComponent method of ViewContainerRef.

this.greetcomp = this.vcr.createComponent(GreetComponent);

You can access all properties and events of the dynamically loaded components using the instance method. So the a value can be passed to the message property as shown in the next code block,

this.greetcomp.instance.message = "Hello dynamic Component";

You can subscribe to the @Output decorated EventEmitter as shown next,

this.greetcomp.instance.messageEvent.subscribe((data:any)=>{ console.log(data); })

Putting everything together, you can lazy load a GreetComponent with the click of a button in the FooComponent, as shown in the following code listing,

const template = ` <button (click)='loadComponent()'>Load Greet Component </button>`@Component({ selector: 'app-foo', standalone: true, imports: [CommonModule], template: template})export class FooComponent { message = "data from parent" greetcomp: any; vcr = inject(ViewContainerRef);  async loadComponent() { this.vcr.clear(); const { GreetComponent } = await import('../greet/greet.component'); this.greetcomp = this.vcr.createComponent(GreetComponent); if (this.greetcomp) { this.greetcomp.instance.message = "Hello dynamic Component"; this.greetcomp.instance.messageEvent.subscribe((data:any)=>{ console.log(data); }) } }}

Currently, Angular loads GreetComponent at the end after all DOM elements of FooComponent. To load it at a specific div block, read the div block as ViewChild and ViewConatinerRef. In the other post, I will cover that in detail.

I hope you find this post helpful. Thanks for reading.


Original Link: https://dev.to/debug_mode/how-to-lazy-and-dynamically-load-a-component-in-angular-18ke

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To