Oops! Looks like there's an issue with creating a shadow root in an Angular Web Component

Creating a basic Angular Web Component. Check out the Github repository that showcases the process here:

https://github.com/fireflysemantics/fs-gist

The component code can be found here: https://github.com/fireflysemantics/fs-gist/blob/master/src/app/fs-gist/fs-gist.component.ts

import { Component, OnInit, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'fs-gist',
  template: `
    <p>
      fs-gist works!
    </p>
  `,
  styles: [
  ],
  encapsulation: ViewEncapsulation.Native
})
export class FsGistComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

}

Here is the module code: https://github.com/fireflysemantics/fs-gist/blob/master/src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { FsGistComponent } from './fs-gist/fs-gist.component';

import { Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';

@NgModule({
  declarations: [
    FsGistComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  entryComponents: [FsGistComponent]
})
export class AppModule {
  constructor(private injector: Injector) {}

  ngDoBootstrap() {
    const el = createCustomElement(
      FsGistComponent, 
      { injector: this.injector });
    customElements.define('fs-gist', el);
  }
}

Explore the build scripts in package.json:

https://github.com/fireflysemantics/fs-gist/blob/master/package.json

    "b": "ng build --prod --output-hashing=none",
    "c": "bash -c 'cat dist/fs-gist/{runtime-es5,polyfills-es5,main-es5}.js > fs-gist.js'",
    "c1": "bash -c 'cat dist/fs-gist/{runtime-es2015,polyfills-es2015,main-es2015}.js > fs-gist2015.js'",
    "p": "npm run b && npm run c",
    "p1": "npm run b && npm run c1",
    "cp-fs-gist": "cp fs-gist.js ../wctest/src/assets/js/"

Executing npm run p will generate the web component fs-gist in the root folder.

This component was then copied into the src/assets/js/ folder of another test project:

https://github.com/fireflysemantics/wc-test

Upon loading the application, an error occurs as seen in the console logs:

fs-gist.js:1 ERROR TypeError: i.createShadowRoot is not a function at new n (fs-gist.js:1) at e.value (fs-gist.js:1) at fs-gist.js:1 at n.value (fs-gist.js:1) at e.value (fs-gist.js:1) at e.value (fs-gist.js:1) at HTMLElement.value (fs-gist.js:1) at ZoneDelegate.invoke (zone-evergreen.js:364) at Object.onInvoke (fs-gist.js:1) at ZoneDelegate.invoke (zone-evergreen.js:363)

To address this issue, polyfills for web components are included in polyfills.js:

import "@webcomponents/custom-elements/src/native-shim";
import "@webcomponents/custom-elements/custom-elements.min";
import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js'

Additionally, web component loading has been added to index.html:


  <script src="webcomponents/webcomponents-loader.js"></script>
  <script>   
  if ( !window.customElements ) 
  { document.write('<!--') } 
  </script>
  <script src="webcomponents/custom-elements-es5-adapter.js"></script> 
  <!-- ! KEEP ME -->

Looking for ideas or solutions to this problem.

In an attempt to simplify things, a minimal environment using the fs-gist web component was created in StackBlitz. The demo imports the web component polyfill from a CDN:

https://stackblitz.com/edit/js-custome-element-test

However, the following error surfaced:

ERROR Error: Failed to execute 'define' on 'CustomElementRegistry': the name "fs-gist" has already been used with this registry

Bug Report

A potential bug is suspected in the Angular compilation process of the web component.

https://github.com/angular/angular-cli/issues/17448

Answer №1

In order to properly implement View Encapsulation, the ViewEncapsulation.ShadowDom component needs to be utilized (Refer to the bug report mentioned above for more details):

import { Component, OnInit, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'fs-gist',
  template: `
    <p>
      fs-gist works!
    </p>
  `,
  styles: [
  ],
  encapsulation: ViewEncapsulation.ShadowDom
})
export class FsGistComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

}


Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring subobjects while fetching observables (typescript/angular)

When retrieving JSON from an API into an Angular service, I am working with a collection of objects structured like this: { "data": { "id": 1, "title": "one" }, "stats" : { "voteCount": 8 } } I am particularly interested in the ' ...

Guidance on transferring information from a parent component to an Angular Material table child component

Currently, I am implementing an angular material table with sorting functionality. You can view the example here: Table Sorting Example I intend to transform this into a reusable component so that in the parent component, all I have to do is pass the colu ...

Transform a struggling Observable into a successful one

When working with an HTTP service that returns an observable, I encountered an error during the subscribe process for a specific use case that I would like to address within the successful path. My scenario looks like this: In my service class: class My ...

Implementing a PhysicsImpostor feature that flips meshes upside-down

After exporting a mesh from Blender and loading it from a GLB file, I encountered an issue with the PhysicsImpostor causing the entire model to flip upside down. Can anyone help me troubleshoot this problem? export class Player extends BABYLON.AbstractMes ...

Troubleshooting column alignment with Bootstrap4 and Angular: Resolving issues with text alignment on

Being relatively new to Bootstrap 4, as I have only used version 3.3 on my previous project which did not utilize the flexbox grid system. Now that I am embarking on a new project, I find myself facing a challenge: I am struggling to apply the "text-alig ...

Unveiling individual modules of an Angular library using public-api.ts in the latest version of Angular (Angular 13)

After completing an upgrade on my Angular library project from version 11 to 13, I encountered an issue when attempting to execute the ng build command. In version 11, the setup looked like this: I had multiple smaller modules, each containing various co ...

The data is not being correctly bound to Angular's ngModel

Why is my two-way binding not functioning correctly? I have imported the forms module and am using banana syntax. Even when attempting reactive forms, the issue persists. The input field is not displaying the predefined value nor updating when interacted w ...

Challenges with utilizing Ionic Native in a cross-platform application

I am currently developing an application using Ionic 2 that can function both as a website in a browser and as a mobile app on iOS and Android. One key aspect of the app is its use of the SQLite plugin when accessed on mobile devices. However, I have encou ...

I am currently struggling with adding an HTML form to my Angular project

Currently utilizing Angular framework My Add button triggers the appending of HTML content upon multiple clicks. The issue arises when I click the Add button, as the appended content fails to display textboxes or dropdowns. Instead, only the field names ...

The dropdown for selecting months and years is not appearing on Angular 13's ngbdatepicker

Currently, I am developing a project in Angular 13 with Bootstrap 4. I am trying to implement a datePicker using ngbDatepicker, but unfortunately, the datePicker is not displaying the dropdowns for selecting months and years at the top. Here is the code sn ...

Updating the global service interface in Angular 2 by making changes in a component and then reflecting these updates in another

Experimenting with Angular 2, I aim to create a global service that houses an interface. This interface should be modifiable through the HeaderComponent. Once the user alters the interface via the HeaderComponent, the change should reflect in another compo ...

Is it possible to use TypeScript in a React Native project with a JavaScript file?

Currently, I am learning React Native by working on app clones like Instagram and YouTube. I have recently started an AirBnb clone project, but I'm facing some issues with the initial build. One issue I noticed is that in 'App.js', the temp ...

Navigating to a component that also needs to redirect

I have a main feature (let's call it "main hub") that houses various sections. Within the "main hub" feature, I navigate to another section (let's call it "subsection") which also contains different subsections. In one of these subsections, call ...

Angular 2 - Implementing a custom base view for all components within a specific directory

I'm currently working on an app that involves user authentication. Once users are logged in, they should have access to an admin sidebar for navigation. However, there are certain pages like Login and Register that won't require the sidebar. Furt ...

What is the process for declaring a set in typescript?

In the documentation on basic types for Typescript, it explains using Arrays as a primitive type I am interested in the syntax: const numbers: string[] = [] How can I achieve the same with a set? ...

What could be the reason for the absence of the Froala editor display

I integrated the Froala editor into my Angular2 project but it doesn't seem to be visible on the screen, and there are no errors present. I made sure to import the necessary modules into app.module.ts, included jQuery in main.ts, and added the scripts ...

Utilizing the ngIf Statement with a Repeating Element: A Step-by-Step

I am working with an Angular Material table: (HTML) <table mat-table [dataSource]="dataSource" multiTemplateDataRows class="mat-elevation-z8"> <ng-container matColumnDef="{{column}}" *ngFor="le ...

What steps should I take to address the numerous errors I am encountering in Atom using the Atom linter tool?

My Atom interface is showing the following errors: {Error running gjslint}(x4) {Error running selective}(x4) Upon checking the errors section, I found the following details: [Linter] Error running selective Error: ENOENT: no such file or directory, open ...

Having trouble resolving 'fs' in the Truffle Box designed for Angular

Currently, I am building an Ethereum decentralized application using the guidelines provided in the following resource: https://github.com/Quintor/angular-truffle-box To successfully implement this, I need to have: truffle @angular/cli ganache-cli In m ...

Issue Error: NG0201: NgControl provider not found within NodeInjector

My creativity has hit a roadblock and I'm looking for some help. I decided to use the Reactive Forms Module in Angular, so I imported it into my app.module.ts as shown below: import { ReactiveFormsModule } from '@angular/forms'; @NgModule({ ...