How to create dynamic template to compile dynamic component with Angular?

Sometimes, we want to create dynamic template to compile dynamic component with Angular.

In this article, we’ll look at how to create dynamic template to compile dynamic component with Angular.

How to create dynamic template to compile dynamic component with Angular?

To create dynamic template to compile dynamic component with Angular, we can use angular-elements.

To install it, we run

npm i @angular/elements

Then we create a service with

import { Injectable, Injector } from "@angular/core";
import { createCustomElement } from "@angular/elements";
import { IStringAnyMap } from "src/app/core/models";
import { AppUserIconComponent } from "src/app/shared";

const COMPONENTS = {
  "user-icon": AppUserIconComponent,
};

@Injectable({
  providedIn: "root",
})
export class DynamicComponentsService {
  constructor(private injector: Injector) {}

  public register(): void {
    Object.entries(COMPONENTS).forEach(([key, component]: [string, any]) => {
      const CustomElement = createCustomElement(component, {
        injector: this.injector,
      });
      customElements.define(key, CustomElement);
    });
  }

  public create(tagName: string, data: IStringAnyMap = {}): HTMLElement {
    const customEl = document.createElement(tagName);

    Object.entries(data).forEach(([key, value]: [string, any]) => {
      customEl[key] = value;
    });

    return customEl;
  }
}

In it, we have the register method that registers the custom components in components.

And then we add the create method to return the custom elements after creating it.

Next, we register our custom component in the component so we can use it within AppComponent.

@Component({
  selector: "app-root",
  template: "<router-outlet></router-outlet>",
})
export class AppComponent {
  constructor(dynamicComponents: DynamicComponentsService) {
    dynamicComponents.register();
  }
}

We inject the dynamicComponents service and call register to use itin AppComponent.

Then we create the dynamic component with

dynamicComponents.create("user-icon", {
  user: {
    //...
  },
});

And then we can use it in our code with

const html = `<div class="wrapper"><user-icon class="user-icon" user='${JSON.stringify(rec.user)}'></user-icon></div>`;
this.content = this.domSanitizer.bypassSecurityTrustHtml(html);

in our component code and with

<div class="comment-item d-flex" [innerHTML]="content"></div>

in the template of the component.

Conclusion

To create dynamic template to compile dynamic component with Angular, we can use angular-elements.