Configuring Modals and Alerts using Dynamic Components in Angular
Senior Frontend Dev. Mostly Angular and Svelte. I will be sharing my day-to-day learning experiences here with the community.
Search for a command to run...
Senior Frontend Dev. Mostly Angular and Svelte. I will be sharing my day-to-day learning experiences here with the community.
No comments yet. Be the first to comment.
Chapter 15 of Comprehensive Guide to SvelteKitAuth: Secure Authentication for SvelteKit Apps
Chapter 14 of Comprehensive Guide to SvelteKitAuth: Secure Authentication for SvelteKit Apps
Chapter 13 of Comprehensive Guide to SvelteKitAuth: Secure Authentication for SvelteKit Apps
Chapter 12 of Comprehensive Guide to SvelteKitAuth: Secure Authentication for SvelteKit Apps
Chapter 11 of Comprehensive Guide to SvelteKitAuth: Secure Authentication for SvelteKit Apps
Dynamic components are essentially components which you create programmatically at runtime. Example, let's say you want to show an alert or a modal which should only be loaded upon a certain action, for example you have an error and you want to show an overlay on the entire screen or something like that, could be done using dynamic components.
Aim is to build scalable and flexible approach to make use of modals and alerts in our project utilizing Angular's Dynamic Component feature.
Helicopter view of approach:
ComponentFactoryResolver.ViewContainerReference using a directive. It invokes factory service, passing the configuration object it received in the process from requesting Component. ComponentFactoryResolver using view reference from container component and configuration object from requesting component.Here is the mental-model chart of above discussion:

Designing Factory Service
ComponentFactoryResolver to create component programmatically and use resolveComponentFactory(<component-name>) method to create desired component. const componentFactory = this.componentFactoryResolver.resolveComponentFactory(dynamicItem.component);
const componentRef = vcr.createComponent(componentFactory);
(componentRef.instance as DynamicComponent).data = dynamicItem.data;
Note: While designing this topic, I have made use of Angular v12.2 & Angular v13 is just about to release in few days. Since v13, dynamic component creation via
ViewContainerRef.createComponentdoes not require resolving component factory: component class can be used directly.
Designing Container Component
div with a local (template) reference along with @ViewChild, we could get access to that but this is not how it works.ViewContainerRef which is essentially an object managed internally by Angular, which gives Angular a reference/pointer to a place in the DOM with which it can interactWe can create a helper directive and now this directive needs to do one important thing, it needs to inject the ViewContainerRef and this automatically gives you access to the reference/pointer at the place where this directive is then used.
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[appDynamicContainerSelector]'
})
export class DynamicContainerSelectorDirective {
constructor(public viewContainerRef: ViewContainerRef) {}
}
Note: we need to turn this into a public property, so that we can access that
ViewContainerReffrom outside.
<ng-container appDynamicContainerSelector></ng-container>
@ViewChild(DynamicContainerSelectorDirective, { static: true }) containerSelector!: DynamicContainerSelectorDirective;
this.configService.loadComponent(viewContainerRef, componentconfig);
ViewContainerRef.clear(), it simply clears all Angular components that have been rendered in that place before.Register Component in app.module
<app-demo>, like this selector, it basically looks into the declarations array, finds it there and then is able to create that component.NgModule. Besides declarations, imports and so on, there is a property entryComponents. Entry components also is an array and it's an array of components types but only of components that will eventually need to be created without a selector or the route config being used. entryComponents: [ModalCompA, AlertCompB]
Designing Configuration Service
Configuring objects for Dynamic Component
We can create a configuration object to specify items that are to be displayed in our modal e.g. header, body contents, links etc. & then dispatch this object to our container component via configuration service.
const modalData: ComponentConfig = {
componentType: 'modal',
dynamicComponentType: StandardModalComponent,
data: {
header: 'Dynamically generated Modal',
header2: 'This is a Standard modal with configuration object',
alert: {
icon: 'alert-warning',
type: 'warning',
size: 'md'
},
modalSize: 'lg',
bodyContent: 'Body Content: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam fermentum, dui et interdum posuere, orci libero sodales magna.',
onClose: () => this.dynamicModalAndAlertConfigService.destroyComponent(),
callsToAction: [{
label: 'Cancel',
HtmlElementType: 'a',
action: () => this.dynamicModalAndAlertConfigService.destroyComponent(),
linkAlign: 'left'
}, {
label: 'Submit',
HtmlElementType: 'button',
action: () => this.dynamicModalAndAlertConfigService.destroyComponent(),
buttonAlign: 'right'
}]
}
};
this.dynamicModalAndAlertConfigService.dispatchComponent(modalData);
Here is the mapping of above object with final outcome:

Standalone Modal/Alert Components
Loading Data messageReference Items
#angular #dynamic-components