Coders beware
Here there be monsters
Last time I have posted the article about dynamic components in Angular. Demonstrated how to set up one. Now here these a warning.
If you pass some kind of subject (behavior or any other) to your dynamic component and you passed it to your entry component (component you actually want to load). You will find your self in trouble.
What are you talking about!?
The example I have demonstrated is perfectly fine. It is clean and has no subscriptions. But when we have a subscription. We need to unsubscribe. Right!
Where do we do unsubscribing? NgOnDestroy.
And there is a problem.
By changing between components NgOnDestroy hook does not fire. That's because we are not destroying the entry component. We are replacing it.
What!!!
Now our app has gone bananas.
Our subscription lives on and if you fire the same event for your all entry component you are in trouble. There are no error messages and the application is showing weird results.
So what do we need to do?
We need to destroy our entry component.
componentRef: ComponentRef<any>; //declaration
this.componentRef.destroy();
This will destroy the component and fire the NgOnDestroy hook.
Example of the code
loadComponent(){
if(this.componentRef){
/** Checkig if an old component reference exists and then we destroy it*/
this.componentRef.destroy();
}
/** Preparing our component for creation */
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.components[this.inputData]);
/** Grabbing reference of our view placeholder */
const viewContainerRef = this.placeholder.viewContainerRef;
/** Clearing our placeholder */
viewContainerRef.clear();
/** Magic of creating a component instance */
this.componentRef = viewContainerRef.createComponent(componentFactory);
/**
* @Input data into our instance.
*/
(this.componentRef.instance as IComp).text = ''+this.inputData;
/** @Output data from our instance */
(this.componentRef.instance as IComp).event.subscribe(
data => this.changeEmit.emit(data)
);
}
I have updated git repo with this code. You can find the link at the end of this article
Lessons learned
Mistakes have the power to turn you into something better than you were before.
Github Repo
markoberger / angular-dynamic-example
Angular Dynamic example
DynamicExample
This project was generated with Angular CLI version 7.3.7.
Development server
Run ng serve
for a dev server. Navigate to http://localhost:4200/
. The app will automatically reload if you change any of the source files.
Code scaffolding
Run ng generate component component-name
to generate a new component. You can also use ng generate directive|pipe|service|class|guard|interface|enum|module
.
Build
Run ng build
to build the project. The build artifacts will be stored in the dist/
directory. Use the --prod
flag for a production build.
Running unit tests
Run ng test
to execute the unit tests via Karma.
Running end-to-end tests
Run ng e2e
to execute the end-to-end tests via Protractor.
Further help
To get more help on the Angular CLI use ng help
or go check out the Angular CLI README.
Top comments (0)