0
votes

The widget is made by custom element(@angular/elements) and it is embedded in angular universal. The way I did it it to add the script tag (angularElements.js) in index.html and custom tag is added in a component.

It works well in angular non-ssr but it throws an exception in ssr mode. A error is constructor of custom element module is called twice and DOMException is thrown.

The code below is a sample code of module for custom element.

declare var require: any;
@NgModule({

})
export class WidgetModule implements DoBootstrap {
  constructor(
    private injector: Injector,
    @Inject(PLATFORM_ID) private platformId: Object
  ) {

  }
  defineCustomElements(fn: any, name: string, component: Type<any>) {
    if ( isPlatformBrowser(this.platformId) ) {
      window.customElements.define(name, fn(component, {injector: this.injector}));
    }
  }
  ngDoBootstrap() {
    console.log('constructor of widget is called.....');
    if ( isPlatformBrowser(this.platformId) ) {
      const { createCustomElement }  = require('@angular/elements');

      this.defineCustomElements(createCustomElement, 'widget-main-schedule', MainScheduleComponent);
    }
  }
}

This is the emebed code in angular universal.

<body>
  <app-root></app-root>
  <script type="text/javascript" src="http://localhost/widgets/angularElements.js"></script>
</body>
</html>

This is the widget sample

<div #main_schedule class="main-schedule">
      <h2>Competition Schedule</h2>
      <!-- this is widget -->
      <widget-main-schedule></widget-main-schedule>
    </div>

Below is error message in console of browser.

 ERROR DOMException: Failed to execute 'define' on 'CustomElementRegistry': this name has already been used with this registry
at CustomElementRegistry.e.(anonymous function) [as define] (http://localhost/widgets/angularElements.js:2:35267)
at t.defineCustomElements (http://localhost/widgets/angularElements.js:4:210330)
at t.ngDoBootstrap (http://localhost/widgets/angularElements.js:4:210525)
1
You are trying to create an Angular-elements with Angular Universal? - Akber Iqbal
Yes. I am trying to add custom elements in angular universal. - Seok Won Kim
this is not how it would work; you use Angular element to create a custom-element for e,g. <seok-won-kim></seok-won-kim> You can then use this custom DOM element in any place... including an Angular Universal project, or vanilla JS or whatever - Akber Iqbal
As your comment, I added tag in component like as <widget-main-schedule></widget-main-schedule> This error message is shown after add tag into component also. - Seok Won Kim
check out this link. - KiraAG

1 Answers

0
votes

I ran into something similar and my solution was to do a check before defining the customElement. In your code, changing it to:

defineCustomElements(fn: any, name: string, component: Type<any>) {
    if ( isPlatformBrowser(this.platformId) ) {
       if (!window.customElements.get(name)) {  
          window.customElements.define(name, fn(component, {injector: this.injector}));
       }
    }
  }

Should get rid of that error for you.