Angular
© Shutterstock / Unconventional

Looking to create a popup model for Angular? In this step-by-step tutorial, Dhananjay Kumar explains how you can create a component dynamically.

In this article, we will learn to create a component dynamically. You may need to load a component dynamically in various scenarios such as want to show a popup model etc.

Let us assume that, we have a component as listed below, which we will load dynamically.

1
2
3
4
5
6
7
8
9
10
11
12
import { Component, Input } from '@angular/core';
  
@Component({
    selector: 'app-message',
    template: `
<h2>{{message}}</h2>
 
`
})
export class MessageComponent {
    @Input() message: string;
}

To load MessageComponent dynamically you need a container. Let us say that we want to load MessageComponent inside AppComponent. We need a container element in the AppComponent.

Template of AppComponent is as below:

1
2
3
4
5
6
7
8
9
<div style="text-align:center">
      
     <h1>
         Welcome to {{ title }}!
     </h1>
 
     <template #messagecontainer>
     </template>
 </div>

As you see that, we have an entry point template or a container template in which we will load MessageComponent dynamically.

In the AppComponent, we need to import following:

  1. ViewChild, ViewContainerRef, and ComponentFactoryResolver from @angular/core
  2. ComponentRef and ComponentFactory from @angular/core
  3. MessageComponent from message.component

After importing required things, AppComponnet will look like following listing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import {
    Component,
    ViewChild,
    ViewContainerRef,
    ComponentFactoryResolver,
    ComponentRef,
    ComponentFactory
} from '@angular/core';
import { MessageComponent } from './message.component';
  
@Component({
    selector: 'app-root',
    templateUrl: './app.component.html'
})
export class AppComponent {
    title = 'app';
}

SEE MORE: Putting Angular and progressive web apps to work in 2018

We can access template as the ViewChild inside the Component class. Template is a container in which, we want to load the component dynamically. Therefore, we have to access temple as ViewConatinerRef.

ViewContainerRef represents container where one or more view can be attached. This can contain two types of views.

  1. Host Views
  2. Embedded Views

Host Views are created by instantiating a component using createComponent and Embedded Views are created by instantiating an Embedded Template using createEmbeddedView. We will use Host Views to dynamically load MessageComponent.

Let us create a variable called entry which will refer template element. In addition, we have injected ComponentFactoryResolver services to component class, which will be needed to dynamically load the component.

1
2
3
4
5
export class AppComponent {
    title = 'app';
    @ViewChild('messagecontainer', { read: ViewContainerRef }) entry: ViewContainerRef;
    constructor(private resolver: ComponentFactoryResolver) { }
}

Keep in mind that entry variable which is reference of template element has API to create components, destroy components etc.

Now to create component, let us create a function. Inside the function, we need to perform following tasks,

  • Clear the container
  • Create a factory for MessageComponent
  • Create component using the factory
  • Pass value for @Input properties using component reference instance method

SEE MORE: On the road to Angular 6: v6 is feature complete! RC phase blasts off

Putting everything, together createComponent function will look like listing below:

1
2
3
4
5
6
createComponent(message) {
    this.entry.clear();
    const factory = this.resolver.resolveComponentFactory(MessageComponent);
    const componentRef = this.entry.createComponent(factory);
    componentRef.instance.message = message;
}

We can call createComponent function on click event of the button. Let us put two buttons in the template and call createComponent function on click of the buttons.

1
2
3
4
5
6
7
8
9
10
11
12
<div style="text-align:center">
     
    <h1>
        Welcome to {{ title }}!
    </h1>
 
    <button (click)="createComponent('Welcome Foo ! ')">Welcome</button>
    <button (click)="createComponent('Foo Again ?')">Not Welcome</button>
     
    <template #messagecontainer>
    </template>
</div>

In output, you can see that component is getting loaded dynamically on click of the button.

Angular

As you click on the buttons component will be reloaded with different message. You can destroy a component using destroy method on the componentRef.

1
2
3
destroyComponent() {
    this.componentRef.destroy();
}

Either you can destroy dynamically loaded component by manually calling the function or put it inside ngOnDestroy() life cycle hook of the component, such that when host component is destroyed automatically dynamically loaded component will also destroy.

SEE MORE: Two years with Angular and loving it

Putting everything together, AppComponent will look like listing below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import {
    Component,
    ViewChild,
    ViewContainerRef,
    ComponentFactoryResolver,
    ComponentRef,
    ComponentFactory
} from '@angular/core';
import { MessageComponent } from './message.component';
  
@Component({
    selector: 'app-root',
    templateUrl: './app.component.html'
})
export class AppComponent {
    title = 'app';
    componentRef: any;
  
    @ViewChild('messagecontainer', { read: ViewContainerRef }) entry: ViewContainerRef;
    constructor(private resolver: ComponentFactoryResolver) { }
  
    createComponent(message) {
        this.entry.clear();
        const factory = this.resolver.resolveComponentFactory(MessageComponent);
        this.componentRef = this.entry.createComponent(factory);
        this.componentRef.instance.message = message;
    }
    destroyComponent() {
        this.componentRef.destroy();
    }
}

At this point on running application, you will get an error because we have not set the entryComponents in the AppModule. We can set that as shown in the listing below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { AppComponent } from './app.component';
import { MessageComponent } from './message.component';
  
@NgModule({
    declarations: [
        AppComponent, MessageComponent
    ],
    imports: [
        BrowserModule
    ],
    providers: [],
    bootstrap: [AppComponent],
    entryComponents: [MessageComponent]
})
export class AppModule { }

This is all you need to do to load a component dynamically in Angular.

SEE MORE: The ‘original’ Angular: Still kicking in 2018

Like this post?

And there you have it! If you like this post, please like it and share it. In addition, if you haven’t checked out Infragistics Ignite UI for Angular, be sure to do so! They’ve got 30+ material based Angular components to help you code speedy web apps faster.

This post was originally published on the Infragistics blog.

Angular 6
© Angular.io / Shutterstock Spring Bine

Angular v6 should be released pretty soon (hopefully!). As we’re getting closer to the grand Angular 6 finale, we start to see bits and pieces of what is shaping up to be a great version. RC.2 is here.

In theory, rc.2 should be the last release candidate, which means Angular v6 is right around the corner. We’re not sure if this is actually going to happen since beta.8 wasn’t planned but still occurred.

Anyway, the third —and possibly the last— release candidate brings seven bugfixes and one feature, namely:

  • compiler-cli: lower loadChildren fields to allow dynamic module paths (#23088) (550433a)

 

Update April 3, 2018

The second release candidate is here and it brings almost 20 bugfixes and two features:

Features

  • bazel: prefix private-export (barred-latin-o) symbols (#23007) (27e14b2)
  • compiler: lower @NgModule ids if needed (#23031) (bd024c0)

 

Update March 29, 2018

We know that Angular v6 is now feature complete so there’s no reason to worry about it.

However, since there are some differences between the tentative schedule and the changelog, one could think that the release date might be pushed back again.

Source: Angular v6 tentative schedule

Of course, it might happen that they release more release candidates at the same time like they did with beta.8 and RC.0. Either way, Angular v6 is in the pipeline and it’s already feature complete so it won’t be long before we’ll have the chance to play with it.

 

Update March 21, 2018

First came beta.8, then came RC.0. There are actually a lot of features in beta.8 (which wasn’t even planned) so you might want to have a look.

There are some breaking changes, too — read more about them here.

Features

That said, Angular 6 is now feature complete. Although the cli and material/cdk parts of the upcoming release, along with the other integrations are still in development, they will be ready by the time Angular 6 is out.

The first release candidate brings six bugfixes and two features.

Features

Last but not least, it seems that Angular 6 will be released in early April, not late March.

Angular 6 release schedule

 

Update March 8, 2018

The last beta is here — unlike bountiful Beta.6, which brought 16 bugfixes, 15 features, and five breaking changes, Beta.7 only contains three bugfixes.

This time next week, we will have entered the release candidate phase. And in three weeks time’, we’ll finally have Angular 6. Good times ahead!