18

I tried searching google and stackoverflow but could not find an answer. So my question is simple "How can i remove current component in angular 2, 4"

example:

<div (click)="remove($event)">Remove Current Component</div>

remove($event) {
    // this.destroy() ????
}

Basically what i want is ComponentRef see this answer ngOnDestroy() which calls this.cmpRef.destroy() :

ngOnDestroy() {
   if(this.cmpRef) {
     this.cmpRef.destroy();
   }    
}

But he is getting the ComponentRef due to dynamically creating the component.

ForOhFor
  • 786
  • 10
  • 16
Touqeer Shafi
  • 5,084
  • 3
  • 28
  • 45

1 Answers1

21

You can use a *ngIf="myBoolean" directive on the component element in the parent template. When myBoolean becomes false, the component will be destroyed.

No more component or DOM element present. (and ngOnDestroy event raised)

If myBoolean becomes true again, a new component will be instantiated.

A new one will appear in DOM (and ngOnInit event raised)

Your click event can emit an event (binded in the parent with the (myEventEmitter) syntax, and a method in the parent component can then just set the boolean to false.

Demonstration on this Plunker. If it doesn't suit your need, consider editing your question to provide more specific details, including a Minimal Complete Verifiable example

Pac0
  • 21,465
  • 8
  • 65
  • 74
  • i can't use *ngIf, i want it to completely remove it from the context of angular and DOM – Touqeer Shafi Aug 24 '17 at 07:47
  • but the ngIf does precisely that, no ? No more DOM component. – Pac0 Aug 24 '17 at 07:48
  • 1
    yes but the reference exists in the angular for later use of `*ngIf` i want component to completely `destory` – Touqeer Shafi Aug 24 '17 at 07:49
  • 1
    But ComponentRef represents reference to **instances** of component. Destroy deletes **instances** of components I am not sure you can do what you want easily (though I would gladly delete this comment and my answer if it turns out to be possible)... Maybe dynamically remove the Module from your application would be the way to go – Pac0 Aug 24 '17 at 07:55
  • but apparently that not possible yet : https://groups.google.com/forum/#!topic/angular/C0TKsfNOVh4 – Pac0 Aug 24 '17 at 07:55
  • anyway, I don't understand why you want to do that. Does the Component source javascript code contains sensitive information that you want to remove from the browser ? – Pac0 Aug 24 '17 at 07:56
  • the component is joint with `jsPlumb` that's why i have to remove it. – Touqeer Shafi Aug 24 '17 at 07:56
  • so it's not a Angular Component ? (declared in a Typescript file with `@Component() export class MyComponent {}`) – Pac0 Aug 24 '17 at 07:58
  • 1
    what do you mean, it is joint with it? doesn't make sense. For example if you use ` ***your component / markup***` there will be nothing in your DOM left of your markup. – malifa Aug 24 '17 at 07:58
  • it is a angular component which is joined with jsPlumb! – Touqeer Shafi Aug 24 '17 at 07:59
  • `this.jsPlumbInstance.addEndpoint(`component-child-element`);` which joins it with the component, now i want this `endPoint` to remove which i can use `jsPlumb` event called `remove(selector)` but after that i also want this component to destroy got it ? – Touqeer Shafi Aug 24 '17 at 08:01
  • What does it mean "joins with the component" ? Does it create something more in DOM inside the Angular component DOM Element ? – Pac0 Aug 24 '17 at 08:02
  • @TouqeerShafi no i don't "got it". There is NO difference at all in destroying a dynamically created component via its ref or using the `*ngIf` directive on a parent element which does it for you. – malifa Aug 24 '17 at 08:10
  • i can't use `*ngIf` because if it has 300 same endpoints then want ?? should i use `*ngIf` for all the components ?? the question is simple `How can i destory the current component from DOM` – Touqeer Shafi Aug 24 '17 at 08:12
  • @TouqeerShafi So... The solution by ngIf ** is the correct way**, it destroys the component instance and **everything** in the DOM – Pac0 Aug 24 '17 at 08:12
  • But `*ngIf` will remain there right. any ways thanks for your suggestion i'll see what i can do. – Touqeer Shafi Aug 24 '17 at 08:13
  • well, you can have an *ngIf for each component instance. You can create a wrapper component to help you manage all the components, or use *ngFor with a "template selector" containing the *ngIf. Anyway, this would be the correct Angular way to go. – Pac0 Aug 24 '17 at 08:14
  • "the *ngIf will remain there right" -> no, it will not – Pac0 Aug 24 '17 at 08:14
  • @TouqeerShafi I have written a [Plunker to demonstrate the point](https://plnkr.co/edit/euZl5yDViJ7WOWJLznQV?p=preview). Please, if it doesn't demonstrate the correct behavior you want, you should edit it or create another one to show some details of what you want to avoid. – Pac0 Aug 24 '17 at 09:02
  • Hi, it looks like your plunker does not work anymore. But i have the exact same situation that you have described in my application, but ngOnDestroy never gets called. I also added a piece of code that prints something once per second and i found that if the *ngIf condition changes to false and than back to true, the pervious component still exists and continues to print its message, and in addition a new one gets created, so then there are two even though only one exists in DOM. – jgosar Jun 21 '18 at 10:37
  • @jgosar Yes, I noticed the plunker isn't wokring too. About your issue, I think it would deserve it's own question. Are you able to create a [mcve] on plunker or stackblitz ? that would be great. – Pac0 Jun 22 '18 at 10:55
  • Such a simple and straight forward trick - why did I not think about that myself?! NgIf does the job. Thanks! – Web Dev Nov 29 '20 at 22:49
  • This solution wouldn't work if we were talking about a component being created using `MatDialog` – Mohamed Karkotly Aug 06 '22 at 19:49