Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOMException: CustomElementRegistry.define 'ust-frontend' has already been defined as a custom element #63

Open
schnalfy opened this issue Sep 8, 2020 · 3 comments

Comments

@schnalfy
Copy link

schnalfy commented Sep 8, 2020

Hello everybody,

i have a problem with "multiple different dynamic elements I would like to load 2 web components. The second compnent always uses the js-file of the first component. Therefore the error 'ust-frontend' has already been defined as a custom element. I have built the web components according to the following pattern.

I hope someone can help me.

Thanks

<< ----------------------------------->>
web component

import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { Router } from '@angular/router';
import { Location} from '@angular/common';
import { createCustomElement } from '@angular/elements';

import { AppComponent } from './app.component';
import { EcbrateComponent } from './component/ecbrate/ecbrate.component';

import { FormsModule } from '@angular/forms';

@NgModule({
declarations: [
AppComponent,
EcbrateComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule
],
providers: [],
entryComponents: [AppComponent]
})
export class AppModule {
constructor(private injector: Injector, private router: Router, private location: Location ) {
const appElement = createCustomElement(AppComponent, {
injector: this.injector
});
console.log('define ecb-frontend');
customElements.define('ecb-frontend', appElement);
console.log('defined ecb-frontend');
console.log(this.location);
this.router.navigateByUrl(this.location.path(true));
console.log(this.router);
this.location.subscribe(data => {
console.log(data);
this.router.navigateByUrl(data.url);
});
}
// tslint:disable-next-line: typedef
ngDoBootstrap() {}
}

<<---------------------------------------------------->>

lazy-element component

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { url } from 'inspector';

@component({
selector: 'app-lazy-element2',
template: <ng-container *ngFor="let c of dynamicConfigs"> {{c.url}} <ax-lazy-element *axLazyElementDynamic= "c.tag, url: c.url; module: true" raised> </ax-lazy-element> </ng-container>
})
export class LazyElement2Component implements OnInit {

elementUrl = '';
elementTag = '';
onDestroy: any;
dynamicConfigs = [];

constructor(readonly activatedRoute: ActivatedRoute) {
/*
this.onDestroy = this.activatedRoute;
// tslint:disable-next-line: deprecation
let componantName = '';
this.onDestroy.url.forEach( item => {
item.forEach( pathItem => {
console.log(pathItem.path);
componantName = pathItem.path;
});
});
this.elementTag = '';
this.elementUrl = 'http://localhost:4201/component/' + componantName + '/' + componantName + '.js';
console.log(this.elementUrl);
this.elementTag = componantName;
*/
this.dynamicConfigs = [
{url: 'http://localhost:4201/component/ust-frontend/ust-frontend.js', tag: 'ust-frontend'},
{url: 'http://localhost:4201/component/ecb-frontend/ecb-frontend.js', tag: 'ecb-frontend'}
];
}

ngOnInit(): void {}

// tslint:disable-next-line: use-lifecycle-interface
ngOnDestroy() {
// this.onDestroy.unsubscribe();
}
}

<< --------------------------- >>
app.module

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { LazyElementsModule } from '@angular-extensions/elements';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './components/header/header.component';
import { HomeComponent } from './components/home/home.component';
import { DynamicLayoutComponent } from './components/dynamic-layout/dynamic-layout.component';
import { LazyElementComponent } from './components/lazy-element/lazy-element.component';
import { MainLayoutComponent } from './components/dynamic-layout/main-layout.component';
import { LoginComponent } from './components/login/login.component';
import { ReactiveFormsModule } from '@angular/forms';
import { LazyElement2Component } from './components/lazy-element2/lazy-element2.component';

@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [
AppComponent,
HeaderComponent,
HomeComponent,
DynamicLayoutComponent,
LazyElementComponent,
LazyElement2Component,
MainLayoutComponent,
LoginComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
LazyElementsModule,
CommonModule,
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}

@tomastrajan
Copy link
Member

tomastrajan commented Sep 11, 2020

Hi @schnalfy !

Could you please properly format your code using 3 back ticks before and 3 back ticks after? Like this

function properlyFormated() {
    console.log('I acutally can read this...')
}

Also, the error says it all currently, you can not register the same element twice so you would most like have to re-organizae your code so that the registration logic happens only once per web-component.

@schnalfy
Copy link
Author

Hello, Tomas,

the problem is that this error occurs when I try to load a second (not the same) web component. At the moment I think that the problem lies in the call of the web component. But that changes hourly ;) Do you have an example where you call two different web components?

Thanks Ralf

web component

import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { Router } from '@angular/router';
import { Location} from '@angular/common';
import { createCustomElement } from '@angular/elements';

import { AppComponent } from './app.component';
import { EcbrateComponent } from './component/ecbrate/ecbrate.component';

import { FormsModule } from '@angular/forms';

@NgModule({
declarations: [
AppComponent,
EcbrateComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule
],
providers: [],
entryComponents: [AppComponent]
})
export class AppModule {
constructor(private injector: Injector, private router: Router, private location: Location ) {
const appElement = createCustomElement(AppComponent, {
injector: this.injector
});
console.log('define ecb-frontend');
customElements.define('ecb-frontend', appElement);
console.log('defined ecb-frontend');
console.log(this.location);
this.router.navigateByUrl(this.location.path(true));
console.log(this.router);
this.location.subscribe(data => {
console.log(data);
this.router.navigateByUrl(data.url);
});
}
// tslint:disable-next-line: typedef
ngDoBootstrap() {}
}

<<---------------------------------------------------->>

lazy-element component

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { url } from 'inspector';

@component({
selector: 'app-lazy-element2',
template: <ng-container *ngFor="let c of dynamicConfigs">
<ax-lazy-element *axLazyElementDynamic= "c.tag, url: c.url; module: true" raised>


})
export class LazyElement2Component implements OnInit {

elementUrl = '';
elementTag = '';
onDestroy: any;
dynamicConfigs = [];

constructor(readonly activatedRoute: ActivatedRoute) {
this.dynamicConfigs = [
{url: 'http://localhost:4201/component/ust-frontend/ust-frontend.js', tag: 'ust-frontend'},
{url: 'http://localhost:4201/component/ecb-frontend/ecb-frontend.js', tag: 'ecb-frontend'}
];
}

ngOnInit(): void {}
}

<< --------------------------- >>
app.module

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { LazyElementsModule } from '@angular-extensions/elements';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './components/header/header.component';
import { HomeComponent } from './components/home/home.component';
import { DynamicLayoutComponent } from './components/dynamic-layout/dynamic-layout.component';
import { LazyElementComponent } from './components/lazy-element/lazy-element.component';
import { MainLayoutComponent } from './components/dynamic-layout/main-layout.component';
import { LoginComponent } from './components/login/login.component';
import { ReactiveFormsModule } from '@angular/forms';
import { LazyElement2Component } from './components/lazy-element2/lazy-element2.component';

@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [
AppComponent,
HeaderComponent,
HomeComponent,
DynamicLayoutComponent,
LazyElementComponent,
LazyElement2Component,
MainLayoutComponent,
LoginComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
LazyElementsModule,
CommonModule,
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}

@janstadt
Copy link

Gonna help this guy out here a bit.

web component

import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { Router } from '@angular/router';
import { Location } from '@angular/common';
import { createCustomElement } from '@angular/elements';

import { AppComponent } from './app.component';
import { EcbrateComponent } from './component/ecbrate/ecbrate.component';

import { FormsModule } from '@angular/forms';

@NgModule({
    declarations: [AppComponent, EcbrateComponent],
    imports: [
        BrowserModule,
        AppRoutingModule,
        FormsModule,
        HttpClientModule
    ],
    providers: [],
    entryComponents: [AppComponent]
})
export class AppModule {
    constructor(private injector: Injector, private router: Router, private location: Location) {
        const appElement = createCustomElement(AppComponent, {
            injector: this.injector
        });
        console.log('define ecb-frontend');
        customElements.define('ecb-frontend', appElement);
        console.log('defined ecb-frontend');
        console.log(this.location);
        this.router.navigateByUrl(this.location.path(true));
        console.log(this.router);
        this.location.subscribe(data => {
            console.log(data);
            this.router.navigateByUrl(data.url);
        });
    }
    // tslint:disable-next-line: typedef
    ngDoBootstrap() { }
}

lazy-element component

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { url } from 'inspector';

@component({
    selector: 'app-lazy-element2',
    template: <ng-container * ngFor="let c of dynamicConfigs">
        <ax-lazy - element * axLazyElementDynamic= "c.tag, url: c.url; module: true" raised >


})
export class LazyElement2Component implements OnInit {

    elementUrl = '';
    elementTag = '';
    onDestroy: any;
    dynamicConfigs = [];

    constructor(readonly activatedRoute: ActivatedRoute) {
        this.dynamicConfigs = [
            { url: 'http://localhost:4201/component/ust-frontend/ust-frontend.js', tag: 'ust-frontend' },
            { url: 'http://localhost:4201/component/ecb-frontend/ecb-frontend.js', tag: 'ecb-frontend' }
        ];
    }

    ngOnInit(): void { }
}

app.module

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { LazyElementsModule } from '@angular-extensions/elements';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './components/header/header.component';
import { HomeComponent } from './components/home/home.component';
import { DynamicLayoutComponent } from './components/dynamic-layout/dynamic-layout.component';
import { LazyElementComponent } from './components/lazy-element/lazy-element.component';
import { MainLayoutComponent } from './components/dynamic-layout/main-layout.component';
import { LoginComponent } from './components/login/login.component';
import { ReactiveFormsModule } from '@angular/forms';
import { LazyElement2Component } from './components/lazy-element2/lazy-element2.component';

@NgModule({
    schemas: [CUSTOM_ELEMENTS_SCHEMA],
    declarations: [
        AppComponent,
        HeaderComponent,
        HomeComponent,
        DynamicLayoutComponent,
        LazyElementComponent,
        LazyElement2Component,
        MainLayoutComponent,
        LoginComponent
    ],
    imports: [
        BrowserModule,
        AppRoutingModule,
        HttpClientModule,
        LazyElementsModule,
        CommonModule,
        ReactiveFormsModule
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule { }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants