Angular 2 Dynamically Add & remove Components

angular 2 remove component from dom angular 2 dispose component angular 2 destroy child component angular 2 componentresolver angular2 componentfactoryresolver example angular 2 component destroy itself angular2 load component on click dynamic component creation in angular 2

Angular 2 gives full control to add or remove component in other component programmatically by simple steps. In this article we are going to see how to add, remove experience component to any other component, we will also try to pass some values to component from parent to child component to see if it is possible or not. It's better to write on plunker so we can test at anytime from anywhere.

Here is the image, which we are going to code:

1214 dynamically add  remove component

Let's create a new component called ExpComponent which we will use to dynamically add on any page. For clarity, we will use html and ts files separately, so create and HTML file named exp.component.html and add following code to it

<form novalidate>
   <div class="row">
     <div class="horizontal-group">
        <div class="col-md-4">
            <input type="text" 
                   placeholder="Language"
                   class="form-control">
        </div>
        <div class="col-md-2">
            <input type="text" 
                   placeholder="Years"
                   class="form-control" >
        </div>
        <div class="col-md-6">
            <button type="submit" class="btn btn-primary"
                  (click)="save()" > Save</button>
            <button type="button" class="btn btn-default"
                  (click)="removeObject()" > Remove</button>
        </div>
     </div>
   </div>
</form>

Since we are learning how to add and remove component to another component, we are not binding the model and saving the data, I know you can easily do it.

If you notice, we have two buttons, save and remove. What is remove button here? To remove the complete component from parent page. Problem here is how to remove the component from another component, we would not have access to that component code, right?

Let's add one variable in this component say _ref: any, add the remove button code like this:

// method to remove the component from parent page
removeObject() {
    this._ref.destroy();
}

Web will see latter how this._ref will be assigned, here is the complete code for component:

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

@Component({
  selector: 'app-exp',
  templateUrl: './exp.component.html'
})
export class ExpComponent {
  _ref:any;   
  removeObject(){
    this._ref.destroy();
  }   
  save(){
    alert('Saved Successfully!');
  }
}

If you know Angular 2 Component, then nothing new to explain.

We will try to add this component to app.component dynamically. When say dynamically means add code by creating object and not by adding html in template.

First of all add a div on the component where we want to add the component dynamically, say:

<div #parent></div> 

We gave a reference name here so we can access it and add component in this div.

We need to import these decorator and classes, from core

  • ViewChild: To get access to a component and its methods, we can use the @ViewChild decorator
  • ComponentFactoryResolver service: is use to render a component object into another component because we don't have $compile in angular 2
  • ViewContainerRef: Represents a container where one or more Views can be attached.

First of all import the component(s) which we want to add dynamically, otherwise it will give error at the time of creating the object.

import { ExpComponent } from './exp.component'

First we need object of container which we declare with div #parent, so add the code in app.component.ts like this:

@ViewChild('parent', { read: ViewContainerRef })    container: ViewContainerRef;

Need to create the object of ComponentFactoryResolver in constructor, change the constructor to:

constructor(private _cfr: ComponentFactoryResolver) { }

Add a button in template section with addComponent method:

<button type="button" 
    (click)="addComponent()"
    class="btn btn-default">Add Experience </button>

Add method addComponent in our app.component.ts file as follow:

addComponent(){
  // check and resolve the component
  var comp = this._cfr.resolveComponentFactory(ExpComponent);
  // Create component inside container
  var expComponent = this.container.createComponent(comp);
  // see explanations
  expComponent.instance._ref = expComponent;
}

For the first two line, comment is enough so what is the last line:

expComponent.instance._ref = expComponent;

Go and check our exp.component.ts file, we created a variable _ref on top. No time to pass the current object of our commponent to that variable.

See the remove button code

this._ref.destroy();

This will destroy only the component in which remove button will be clicked.

Let me share the complete code of app.component.ts as well:

import {Component} from '@angular/core'
import { Component, 
         OnInit, 
         ViewChild, 
         ComponentFactoryResolver,
         ViewContainerRef } from '@angular/core';
import { ExpComponent } from './exp.component'

@Component({
  selector: 'my-app',
  template: ` <h4>Add/Remove experience</h4>
             <div #parent></div>
             <div>
               <button type="button" 
                      (click)="addComponent()"
                      class="btn btn-default">Add Experience </button>
             </div>`
})
export class AppComponent implements OnInit{ 

  @ViewChild('parent', { read: ViewContainerRef }) container: ViewContainerRef;

   constructor(private _cfr: ComponentFactoryResolver) { }
   ngOnInit(){ }

  addComponent(){    
      var comp = this._cfr.resolveComponentFactory(ExpComponent);
      var expComponent = this.container.createComponent(comp);
      expComponent.instance._ref = expComponent;
  }
}

Check this working plunker:

Note:

If you open the app.module.ts file we added something

entryComponents: [ExpComponent]

It is already deprecated, it is not needed anymore in new versions but I created plunker with old version so ....

One more thing: after clicking the save button it will remove all the controls, this is also due to the old version, please update with new version and everything will be ok.

Some people ask, how to get and save data? for that just added two variables lang and exp and bind them with ngModel and show the entered value in alert. I know this is not correct way to bind the model and create property of every variables on component and still it is missing validation, a number field can accept anything here (year of experience), for validation and how to bind the form with different properties of how to create reactive form with Form Builder see angular 5 form validation easiest way and Angular 5 email & compare password validation, different ways

Ali Adravi Having 13+ years of experience in Microsoft Technologies (C#, ASP.Net, MVC and SQL Server). Worked with Metaoption LLC, for more than 9 years and still with the same company. Always ready to learn new technologies and tricks.
  • angular2
  • angularjs
By Ali Adravi On 27 Aug, 17  Viewed: 50,294

Other blogs you may like

Angular component communication by using Input Output decorator

@Input and @Output decorator ar used to pass data/communicate between components, @input is used to pass data from parent to child component on the other hand @Output is use to notify the parent by using EventEmitter. Take the simple example of customers list parent page and add/edit child... By Ali Adravi   On 30 Sep 2017  Viewed: 2,107

Angular 4 upload files with data and web api by drag & drop

Upload file with data by clicking on button or by drag and drop, is the topic of this article. We will try to create an image gallery by uploading files and save data into database and images into a folder. We will try to create a component in a way that it can be used anywhere in entire... By Ali Adravi   On 24 Sep 2017  Viewed: 40,971

Angular 2 CRUD with Web API 2

Angular 2 insert update, delete, search, sort feature we will try in this article which we will improve with dynamic component loading and image upload with drag and drop feature in coming articles with the same base code. We are going to use Angular-CLI 4 for this application. What we need to... By Ali Adravi   On 03 Sep 2017  Viewed: 25,716

Angular 2 Accordion expand only one at a time

Createing accordion demo in Angular 2 is more than easy, Angular have rich of conditional features which we will see in this article, like how to apply more than one class on the basis of some conditional values. For this demo we are not goign to write some fancy CSS and animation but use the... By Ali Adravi   On 19 May 2017  Viewed: 11,878

Angular 2 Page Title Static and Dynamic with built-in Title Service

Angular 2 have a built-in service called Title, while in angularjs or angular 1 we were maintaining it through the routing or through the service. By using the Title service provided by Angular 2, in 2 minute every thing will be set without any complication, even we don't need to understand the... By Ali Adravi   On 14 Apr 2017  Viewed: 5,024