Angular Dynamic Component Loading

Learn Angular Dynamic Component Loading with ViewContainerRef, createComponent(), lazy loading, standalone components, dynamic dialogs, dashboards, plugin architecture, Mermaid diagrams, and interview questions.

Modern Angular applications often need to create components at runtime instead of compile time.

Examples include:

  • Popup dialogs
  • Notification messages
  • Dynamic dashboards
  • Plugin architectures
  • Dynamic forms
  • CMS-driven pages
  • Widget systems
  • Micro Frontends

Angular provides Dynamic Component Loading, allowing applications to create, insert, update, and destroy components programmatically.

Since Angular 14+, dynamic component creation has become much simpler using ViewContainerRef.createComponent() without requiring ComponentFactoryResolver.

This is a Senior Angular Developer interview topic frequently asked in enterprise projects.


Table of Contents

  • What is Dynamic Component Loading?
  • Why Use Dynamic Components?
  • Dynamic Component Architecture
  • ViewContainerRef
  • createComponent()
  • Destroying Components
  • Passing Data
  • Listening to Events
  • Lazy Loading Components
  • Dynamic Dialog Example
  • Plugin Architecture
  • Best Practices
  • Top 10 Interview Questions
  • Summary

What is Dynamic Component Loading?

Dynamic Component Loading is the process of creating Angular components during runtime instead of declaring them directly inside templates.

Instead of:

<app-user></app-user>

Angular creates the component programmatically.


Why Dynamic Components?

Dynamic components are useful when:

  • Component type is unknown until runtime
  • User selects which screen to display
  • Dashboard widgets are configurable
  • CMS determines page layout
  • Dialogs and popups appear dynamically
  • Plugins are loaded on demand

Static vs Dynamic Components

Static Component Dynamic Component
Declared in HTML Created using TypeScript
Exists during compilation Created at runtime
Always rendered Rendered only when needed
Less flexible Highly flexible
Simpler More powerful

Dynamic Component Architecture

flowchart TD
    A[Application]
    B[Parent Component]
    C[ViewContainerRef]
    D["createComponent()"]
    E[Dynamic Component]
    F[Browser]

    A --> B
    B --> C
    C --> D
    D --> E
    E --> F

How Dynamic Loading Works

sequenceDiagram

participant User

participant Parent

participant ViewContainerRef

participant Angular

participant Component

User->>Parent: Click Button

Parent->>ViewContainerRef: createComponent()

ViewContainerRef->>Angular: Instantiate Component

Angular-->>Component: Initialize

Component-->>User: Display UI

ViewContainerRef

ViewContainerRef represents a location where Angular can insert views dynamically.

import {
ViewContainerRef
} from '@angular/core';

constructor(

private viewContainer:

ViewContainerRef

){}

Think of it as an empty placeholder where Angular can insert components.


Basic Dynamic Component

User Component

@Component({
    selector:'app-user',
    standalone:true,
    template:`
      <h2>User Component Loaded</h2>
    `
})
export class UserComponent{}

Parent Component

import {
Component,
ViewContainerRef
} from '@angular/core';

@Component({
    selector:'app-root',
    standalone:true,
    template:`
      <button
      (click)="loadComponent()">
      Load
      </button>
    `
})
export class AppComponent{

constructor(

private container:

ViewContainerRef

){}

loadComponent(){

this.container.createComponent(

UserComponent

);

}

}

Output

User Component Loaded

createComponent()

Angular 14+ introduced a simplified API.

this.container.createComponent(

UserComponent

);

Advantages:

  • Simple API
  • No ComponentFactoryResolver
  • Supports Standalone Components
  • Better performance

Dynamic Loading Flow

flowchart LR
    A["Button Click"] --> B["ViewContainerRef"]
    B --> C["createComponent()"]
    C --> D["Component Instance"]
    D --> E["Browser"]

Passing Data to Dynamic Components

const componentRef =

this.container.createComponent(

UserComponent

);

componentRef.instance.username =

"Venu";

Dynamic components expose public properties just like normal components.


Child Component

export class UserComponent{

username="";

}

Communication Flow

flowchart TD

Parent

Parent --> ComponentRef

ComponentRef --> Child

Parent --> SetInput

SetInput --> Child

Listening to Output Events

Dynamic components can emit events.

Child Component

@Output()

saved =

new EventEmitter<string>();

Parent

componentRef.instance.saved

.subscribe(

value=>console.log(value)

);

Destroying Dynamic Components

componentRef.destroy();

Or

this.container.clear();

Destroying components releases memory and removes them from the DOM.


Dynamic Lifecycle

flowchart TD

Create

Create --> OnInit

OnInit --> Render

Render --> UserInteraction

UserInteraction --> Destroy

Destroy --> OnDestroy

Clearing Existing Components

this.container.clear();

Useful when loading only one component at a time.


Multiple Dynamic Components

this.container.createComponent(

HeaderComponent

);

this.container.createComponent(

ContentComponent

);

this.container.createComponent(

FooterComponent

);

Result

Header

Content

Footer

Lazy Loading Dynamic Components

Large applications often lazy-load components.

const {

ReportsComponent

}

=

await import(

'./reports.component'

);

this.container.createComponent(

ReportsComponent

);

Benefits:

  • Smaller initial bundle
  • Faster startup
  • Better scalability
  • Improved user experience

Lazy Loading Flow

graph TD
    A["User Action"]
    B["Dynamic Import"]
    C["Download Lazy Chunk"]
    D["createComponent()"]
    E["Render in Browser"]

    A --> B
    B --> C
    C --> D
    D --> E

Dynamic Dialog Example

graph TD
    A[Button Click] --> B[Dialog Service]
    B --> C[Create Component]
    C --> D[Dialog Component]
    D --> E[Overlay]

Example:

openDialog(){

this.container.createComponent(

DialogComponent

);

}

Dynamic Dashboard Example

Imagine a banking dashboard.

flowchart TD

Dashboard

Dashboard --> AccountsWidget

Dashboard --> BalanceWidget

Dashboard --> LoanWidget

Dashboard --> InvestmentWidget

Users choose which widgets to display.

Angular loads only the selected widgets dynamically.


Plugin Architecture

Large enterprise applications support plugins.

flowchart TD

Application

Application --> PluginManager

PluginManager --> PluginA

PluginManager --> PluginB

PluginManager --> PluginC

Each plugin is loaded dynamically at runtime without modifying the core application.


Dynamic Form Example

flowchart TD

JSONConfiguration

JSONConfiguration --> ComponentFactory

ComponentFactory --> TextField

ComponentFactory --> DatePicker

ComponentFactory --> Checkbox

ComponentFactory --> Dropdown

The UI is generated from metadata instead of hardcoded HTML.


ComponentFactoryResolver (Legacy)

Before Angular 14:

ComponentFactoryResolver

After Angular 14:

createComponent()
Angular <14 Angular 14+
ComponentFactoryResolver createComponent()
More Boilerplate Cleaner API
Factory Required Direct Component Creation

Common Use Cases

Requirement Solution
Popup Dynamic Component
Dialog Dynamic Component
Dashboard Widgets Dynamic Loading
CMS Pages Dynamic Loading
Plugin System Dynamic Loading
Notifications Dynamic Components
Wizard Steps Runtime Components
Dynamic Forms Metadata + Components

Best Practices

  • Prefer createComponent() over ComponentFactoryResolver.
  • Lazy-load large components.
  • Destroy unused components.
  • Keep dynamic components standalone where possible.
  • Avoid unnecessary component recreation.
  • Use dependency injection instead of global variables.
  • Keep component communication loosely coupled.

Common Mistakes

  • Forgetting to destroy dynamically created components.
  • Creating duplicate components without clearing the container.
  • Loading large components eagerly.
  • Storing business logic in the dynamic loader.
  • Using dynamic loading when simple routing is sufficient.

Advantages

Feature Benefit
Runtime UI Flexible interfaces
Lazy Loading Better performance
Plugin Support Extensible applications
Dashboard Widgets Configurable layouts
Dialog Creation Cleaner architecture
Standalone Components Simpler implementation

Top 10 Angular Dynamic Component Loading Interview Questions

1. What is Dynamic Component Loading?

Answer

Dynamic Component Loading is the process of creating Angular components programmatically at runtime instead of declaring them in templates.


2. Which Angular API is used for dynamic component creation?

Answer

Angular uses ViewContainerRef.createComponent() to create components dynamically.


3. What is ViewContainerRef?

Answer

ViewContainerRef represents a container where Angular can insert, remove, or manage views and dynamically created components.


4. What is createComponent()?

Answer

createComponent() is the modern Angular API for instantiating a component dynamically and adding it to a ViewContainerRef.


5. How do you pass data to a dynamically created component?

Answer

After creating the component, assign values to its public properties or use ComponentRef.setInput() (Angular 16+) for input properties.

Example:

const ref = this.container.createComponent(UserComponent);

ref.setInput('username', 'Venu');

6. How do you destroy a dynamically created component?

Answer

Use:

componentRef.destroy();

or remove all dynamically created views with:

this.container.clear();

7. Why should components be lazy-loaded?

Answer

Lazy loading reduces the application's initial bundle size, improves startup performance, and loads code only when required.


8. What replaced ComponentFactoryResolver?

Answer

Since Angular 14, ViewContainerRef.createComponent() replaced most uses of ComponentFactoryResolver, resulting in cleaner and simpler code.


9. What are common real-world use cases for Dynamic Component Loading?

Answer

  • Modal dialogs
  • Notification popups
  • Dynamic dashboards
  • CMS-driven pages
  • Plugin systems
  • Dynamic forms
  • Micro Frontend shells

10. What are the best practices for Dynamic Component Loading?

Answer

  • Prefer standalone components.
  • Use createComponent().
  • Destroy components when they are no longer needed.
  • Lazy-load large components.
  • Keep communication through @Input(), @Output(), or services.
  • Avoid unnecessary dynamic creation when static templates or routing are sufficient.

Interview Cheat Sheet

Topic Remember
Runtime Creation createComponent()
Container ViewContainerRef
Return Type ComponentRef<T>
Pass Inputs setInput() or instance
Listen Events @Output() subscriptions
Destroy destroy()
Remove All clear()
Lazy Load import()
Legacy API ComponentFactoryResolver
Angular 14+ Modern Dynamic Loading

Summary

Dynamic Component Loading enables Angular applications to create and manage components at runtime, making it ideal for dialogs, dashboards, plugins, CMS-driven pages, and configurable user interfaces. Modern Angular simplifies this process with ViewContainerRef.createComponent(), eliminating the need for ComponentFactoryResolver. Combined with lazy loading, standalone components, and proper lifecycle management, dynamic component loading provides a scalable and high-performance solution for enterprise Angular applications.


Key Takeaways

  • ✔ Use ViewContainerRef as the insertion point.
  • ✔ Prefer createComponent() in Angular 14+.
  • ✔ Use setInput() or ComponentRef.instance to pass data.
  • ✔ Subscribe to @Output() events when needed.
  • ✔ Destroy components to prevent memory leaks.
  • ✔ Combine with lazy loading for optimal performance.
  • ✔ Ideal for enterprise dashboards, dialogs, plugin systems, and dynamic forms.

Next Article

➡️ 19-Angular-Data-Binding-QA.md