Search code examples
angularcustom-elementangular-elements

Multiple Custom element developed in angular element in single page


I developed 2 custom elements in different Angular element projects and when I try to use them in single html I get error "Failed to execute 'define' on 'CustomElementRegistry': this name has already been used with this registry" How to followed this link to develop https://medium.freecodecamp.org/how-to-create-angular-6-custom-elements-web-components-c88814dc6e0a

I know its something related to loading libs twice packaged in both custom elements. How to resolve this?

Thanks


Solution

  • The Problem: Elements packages up the entirety of Angular and plops it out as a single JS file. When two of these run on a single page, some awful and strange conflicts occur that may or may not affect how your elements behave (more than likely, it will).

    The Solution: The only way I have been able to get 2 angular elements to work flawlessly on a single page is to combine them into a single application. They are still separate elements, meaning you can include those custom tags anywhere on the page independently of the other.

    You can still follow the steps to build a custom element, but in your app.module.ts file just tack on whatever other elements you want to define:

      ngDoBootstrap() {
        const ele1= createCustomElement(ComponentOne, { injector: this.injector });
        customElements.define('my-ele-one', ele1);
    
        const ele2= createCustomElement(ComponentTwo, { injector: this.injector });
        customElements.define('my-ele-two', ele2);
    
        const ele3= createCustomElement(ComponentThree, { injector: this.injector });
        customElements.define('my-ele-three', ele3);
    
        ....
      }
    

    and your HTML could look something like

    <h1> My Elements </h1>
    
    <my-ele-one></my-ele-one>
    
    <p>What a cool element!</p>
    
    <my-ele-two></my-ele-two>
    
    <div class='turtle'>
     <p><my-ele-three></my-ele-three></p>
    </div>
    

    This may even cut down your overall page overhead, since now you won't have two full applications being pulled in.

    I probably spent 50+ hours trying to configure two separate Angular Elements applications to work together to no avail. I did need to support all browsers which was definitely a huge factor, as I could get certain configurations to work in either Chrome, or IE, but not both. My elements were not simple elements either, they had a lot of working parts (bootstrap modals, ag-grids, etc.). Hope this helps someone in the future.