publication

Create Angular Component after Application Initializes

Miquel Canal

Sunday 17, June 2018
  • Angular

How To Create Angular Components Dynamically?

To instantiate a component in an Angular application is quite simple. You should use the selector decorator, i.e. app-my-component, inside the HTML view and Angular takes care of the rest.

However, there might be occasions when your application needs to create new components after Angular initialises. An example for this to occur is an application that fetches data from an external API service and should render a set of components based on the response.

Angular offers build-in tools that allow the creation of components on running time applications. You can picture this as rendering components to the DOM on the fly. Direct access to the DOM or manual injection of html code if highly discouraged in Angular and their recommendation is to use build-in tools.

To showcase a simple example, I am going to use two simple components: a parent and its child.

The parent will be rendered when the Angular application loads. Then a new instance of the child component is going to be created inside the < div > container of the parent component.
Here is a link to the working example on Stackblitz.

Parent Component (HTML)

@Component({
    selector: 'app-parent',
    template: `
        <div>
            <h1>Hi, I am the Parent Component.</h1>
            <span>I will create a dynamic component in 3 seconds...</span>
            <div #container></div>
        <div>`
})
export class AppComponent implements OnInit {
    @ViewChild( 'container', {read: ViewContainerRef} ) container;
    private child = ChildComponent;

    constructor( private resolver: ComponentFactoryResolver ) {
    }

    ngOnInit() {
        // Timeout to simulate async behaviour.
        setTimeout( () => {

            // Creation of a factory component.
            const factory: ComponentFactory<any> = this.resolver.resolveComponentFactory( this.child );

            // Renders the factory into the container and gets the instance.
            const instance = this.container.createComponent( factory );

            // Now "instance" contains the component class. 
            // You are now able to access the component methods from the parent.
        }, 3000);
    }
}

Child Component (HTML)

<h4>This is the Child Component</h4>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. </p>

The real magic: resolveComponentFactory

The ComponentFactoryResolver is an Angular base class that allows to create a component dynamically. It creates a fresh new instance of a given component. After creating the instance, you can render it inside a container using the @ViewChild decorator.

If we take a closer look at the logic section of the parent component, we can see how the resolveComponentFactory gets passed in the constructor and then used to create a new instance of the child component. After a new instance gets created, we just need add it to the container using the createComponent method.

// Creation of a factory component.
const factory: ComponentFactory = this.resolver.resolveComponentFactory( this.child );

// Renders the factory into the container and gets the instance.
const instance = this.container.createComponent( factory );

The returning value of createComponent method is an instance of the chilComponent. That allows you to access the properties and call methods of the childComponent from the parentComponent. This is a powerfull tool to create Angular components Dynamically.

Angular: Data Binding

Angular: Data Binding

Data communication between the logic component and DOM elements of an Angular application.

How to compile Angular into single bundle.

How to compile Angular into single bundle.

Steps to compile an Angular application into a single bundle. An overview of the types of Angular compilation bundles and ways to cache bust an Angular application.

Angular: ViewChild and Local References

Angular: ViewChild and Local References

Access DOM elements directly using viewChild and Template Reference Variables.

This site uses cookies to ensure a great experience. By continue navigating through the site you accept the storage of these cookies.