All topics
Advancedadvanced

Dynamic Component Creation

Explain how to imperatively create a component instance at runtime using ViewContainerRef.createComponent.

Beyond the declarative NgComponentOutlet (covered in the components group), Angular exposes a lower-level, fully imperative API for creating component instances at runtime: ViewContainerRef.createComponent(ComponentType). Interviewers ask about this specifically to check whether you understand what's actually happening underneath higher-level abstractions like NgComponentOutlet, a router's component activation, or a modal/dialog service's internals — all of which are built on exactly this primitive.

It's like a stage manager who can summon an actor onto the stage at any arbitrary moment during a live show based on the plot's needs, rather than every actor's entrance being fixed in the printed script ahead of time — but that same stage manager is now also personally responsible for escorting that actor back offstage when their scene ends.

Key Concepts

1
Calling viewContainerRef.createComponent(MyComponent) compiles (if not already compiled) and instantiates MyComponent, resolving its constructor dependencies through the injector associated with that ViewContainerRef (or an explicitly provided custom injector, letting you inject values into the dynamically created component that wouldn't otherwise be available through the ambient injector hierarchy), and inserts its host view into the DOM at the container's location. The returned ComponentRef gives you direct, imperative access to the new instance's public properties (to set inputs manually) and its instance, location, and destroy() method for later manual cleanup.
viewContainerRef.createComponent(MyComponent)MyComponentViewContainerRefComponentRefinstance
2
This is the mechanism behind building things like a programmatic toast/notification service or a modal dialog service, where components need to be created and destroyed based on arbitrary application logic (a service method call) rather than a fixed position in a static template — the service holds a reference to a ViewContainerRef (often anchored to a dedicated overlay container element) and calls createComponent() whenever a new toast/dialog needs to appear, later calling .destroy() on the returned ComponentRef to remove it.
ViewContainerRefcreateComponent().destroy()ComponentRef
3
A thorough interview answer notes the responsibility this hands you: unlike a component declared in a template (whose lifecycle Angular manages automatically), a dynamically created component's destruction is entirely your responsibility — forgetting to call componentRef.destroy() when it's no longer needed leaks that component instance (and anything it holds onto) indefinitely, which is a very real, easy-to-introduce bug in hand-rolled dynamic component code.
componentRef.destroy()