Mastering Dynamic Components in Angular: Best Tips for Developers

dynamic components in angular best tips for developers

What is a dynamic component in Angular?

Dynamic Components are a powerful feature in Angular that allows for the creation and rendering of components at runtime. This means that components can be injected into a container based on user interaction, allowing for greater flexibility and customization in large-scale applications. It’s important to note that while dynamic loading of components is possible, there are limitations to what can be loaded at runtime while custom Angular Development. Components must be defined within the project or imported into an Angular module, as Angular needs to have a grasp on every component at build time. Nevertheless, dynamic component loading remains a valuable tool for developers looking to create dynamic and responsive applications with Angular.

Is it possible to dynamically load a dynamic component in Angular?

Yes, it is possible to dynamically load a dynamic component in Angular. Dynamic components are created and rendered at runtime, so they can be loaded into a container based on user interaction or other programmatic events. This means that you can dynamically load a component that is itself created dynamically, resulting in a highly flexible and responsive application architecture. However, it’s important to keep in mind that all dynamically loaded components must be defined within the project or imported into an Angular module to ensure that Angular has a grasp on every component at build time. 

How to create a dynamic component in Angular?

To create a dynamic component in Angular, you first need to define a component factory. A component factory is a class that creates an instance of a component and provides information about that component, such as its inputs and outputs.

Here is an example of how to create a dynamic component in Angular:

  1. Define the component that you want to create dynamically. For example, let’s say you want to create a component called “MyDynamicComponent”.
  2. Create a component factory using the ComponentFactoryResolver. The ComponentFactoryResolver is a service that Angular provides to create a factory for a given component.

import { Component, ComponentFactoryResolver, ViewChild, ViewContainerRef } from ‘@angular/core’;

import { MyDynamicComponent } from ‘./my-dynamic.component’;

@Component({

  selector: ‘app-root’,

  template: `

    <div #container></div>

    <button (click)=”createComponent()”>Create Component</button>

  `,

})

export class AppComponent {

  @ViewChild(‘container’, { read: ViewContainerRef }) container: ViewContainerRef;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) {}

  createComponent() {

    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(MyDynamicComponent);

    const componentRef = this.container.createComponent(componentFactory);

  }

}

  1. Use the component factory to create an instance of the component. You can then attach this instance to a view container using the createComponent() method.

By following these steps, you can create dynamic components in Angular and load them into your application as needed.

Let’s discuss this in detail.  

The ‘dynamic’ in dynamic components refers to the fact that they are not defined at build time (but are created during runtime), and they are not referenced inside the templates.

While they do not appear until a certain condition is satisfied or an event occurs, we want to declare them during build-time inside a module since Angular requires a compilation context and new components must always be tied to a module.

This suggests that Angular is aware of the component during development but only produces it at runtime.


One way (although deprecated) was to use the ComponentFactoryResolver.

ComponentFactoryResolver:-

Take note that ComponentFactoryResolver has been deprecated since Angular 13, and the framework does not need Component factories. We will make use of Component classes directly.

The ComponentFactoryResolver is used to locate component factories that wish to build particular instances of components. We use the resolver interface to acquire the factory for the component before creating them with the supplied create () function.

<ng-template #id></ng-template>

If you examine this code in any current IDE, you’ll note that both the ComponentFactoryResolver reference and the createComponent () function are marked as deprecated.

The type ComponentRef indicates that this component was built dynamically by a component factory.

We now have accessibility to the Angular component’s instance and may supply attributes or directly impact the instance’s lifetime, including the destroy () function.  

ComponentFactoryResolver and createComponent() are deprecated

All we can do at this point is supply the instance’s attributes, such as this:

Those final three lines set the component instance’s property values directly.

Directly creating components: 

Instead of leveraging the resolver, we will directly define component classes. And it might be as simple as calling ViewContainerRef.createComponent without using a factory!

The strategy performs the same function (instantiates the component and inserts it into the container) and has an optional set of parameters called options, which configures properties such as the index at which to insert the component into the host, the injector used for the new component, a list of projected nodes, and a module reference that ensures all providers are available for the component. A more extensive explanation is frequently available on the official createComponent page.

This is as simple as writing the following:

   const componentRef = this.view2.createComponent(IdComponent);

     componentRef.instance.backgroundColor = ‘pink’;

                               componentRef.instance.foregroundColor = ‘black’;

                               componentRef.instance.fontWeight = ‘normal’;

  • Format the dynamic components: –

All of the messages contain information to display. The information always includes a URL as well as additional stuff that is unique to each component.

Let us define the interface that will be used to support the message data. To create the interface, use the following command.

ng generates an interface message

There will be three message forms, one for each dynamic component.

As a result, we will establish a message type, standardized data attributes, and a category that contains the kind and data properties.

Replace the contents of src/app/message.ts with the following code.

When we developed the dynamic components before, we used the same base interface, Dynamic Component. Because each dynamic component has some data, we want to alter the Dynamic Component interface to reflect this common property that each component will implement.

Add a property named data of type Message Data to src/app/protected/department/dynamic.component.ts. The interface now appears to be the following one.

export interface DynamicComponent 


    data: MessageData;  

}

We keep the logic simple since we have different components that are particularly intended to handle each message type.

We’ll make template adjustments to each component and implement all interface members by adding an input property that simply accepts the data.

To begin, navigate to src/app/protected/department/clawesome.component.ts. The data for this component includes a Link to an image as well as string information. Update the component to the following.

Each component might be a Material card control with an image to display. Next, navigate to src/app/protected/department/pawesome.component.ts. Also, the URL, content contains the names and descriptions of the attributes. Update the component to the following. 

Finally, open src/app/protected/department/smiley.component.ts. the sole data during this message type is the URL. Update the component to the subsequent.

@Component({ 
  selector: ‘app-smiley’, 
template: ` 
  <mat-card class=”card”>
    <img mat-card-image src=”{{data.url}}” alt=”Photo of a smiley creature”> 
          <mat-card-content>
        <p>SMILE! </p>
                  </mat-card-content>
    </mat-card> `, 
styles: [` .card { max-width: 300px;} `]
          }) 
            export class SmileyComponent implements DynamicComponent { 
            @Input() public data!: MessageData; 
        }

Conclusion: – 

In conclusion, Dynamic Components are a powerful feature in Angular that allow for the creation and rendering of components at runtime. They provide a flexible and efficient way to load components into an application based on user interaction or other programmatic events. By referring to a container using a template variable and injecting newly created components into it, developers can create dynamic and responsive applications that are easier to build and maintain. Overall, Dynamic Components are the best approach to loading components at runtime in Angular, as they provide greater flexibility and customization options for large-scale applications.