Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymer LitElement & Angular - render never called, no content displayed

I want to use Polymers LitElement in my Angular application.

For that, I created an example component (test.js) in the assets folder of my application, and imported it in the index.html.

test.js:

// Import the LitElement base class and html helper function
import { LitElement, html } from '../../../node_modules/lit-element/lit-element';

// Extend the LitElement base class
class Test extends LitElement {

  render(){
    return html`
      <h1>Test works!</h1>
    `;
  }
}
// Register the new element with the browser.
customElements.define('ti8m-test', Test);

index.html:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>NgInAction</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">

  <script type="module" src="/assets/comp-new/default/src/ti8m/test.js"></script>

</head>
<body>
  <app-root></app-root>
</body>
</html>

I installed lit-element in the comp-new directory, using npm install --prefix ./ lit-element.

I also did a npm install lit-element in the project itself, so the npm module is definitely available.

However, when I run my Angular application using ng serve, and navigate to the URL where I included my test component, I find my component in the DOM (using the inspector), but there is no content displayed. Also, when I put a console.log into the render function, I never see the output in the browser. So it looks like the method is never actually called.

Here's how it looks in the DOM:

enter image description here

Here's my project structure:

enter image description here

like image 879
platzhersh Avatar asked Dec 24 '22 00:12

platzhersh


1 Answers

Alright. Once again, solving my own problems, hoping to help anyone with a similar issue ;)

First off: My approach was not the best. I wouldn't recommend putting your custom elements into the assets folder. Usually you would get your custom elements by installing an npm module, so I moved the components into the project structure. Like this, I could also get rid of the additional node_modules and the imports got a lot easier to handle.

How to use Lit Element Custom Components in Angular:

  1. Install lit-elemnt in your project: npm install --save lit-element
  2. Create a folder in your src/app folder for all the custom components (i.e. custom-components)
  3. Create your component (JS or TS, I chose TS)

import { LitElement, html } from 'lit-element';

// Extend the LitElement base class
// export the class, so it can be imported where it is needed
export class Ti8mTestComponent extends LitElement {

  /**
   * Implement `render` to define a template for your element.
   *
   * You must provide an implementation of `render` for any element
   * that uses LitElement as a base class.
   */
  render() {
    /**
     * `render` must return a lit-html `TemplateResult`.
     *
     * To create a `TemplateResult`, tag a JavaScript template literal
     * with the `html` helper function:
     */

    console.log('test-component', this);
    return html`
      <h1>Test works!</h1>
      <p>For real though!</p>
    `;
  }
}

Notice how I left out the customElements.define('ti8m-test', Ti8mTestComponent) part. We'll get to this in a second.

  1. You can define your custom elements wherever you want in your code. I suggest either main.ts, an NgModule, or in the constructor of the component where you want to use the element.

    import {Ti8mTestComponent} from './app/custom-elements/ti8m/test'; ... customElements.define('ti8m-test', Ti8mTestComponent);

That's it! Your Lit Element should be visible in your application now! :-)

Notes:

  1. I had to update to Angular 7, since that's the first version to use Typescript > 3, which is needed for the Lit Element npm module. (Lit Element is using type unknown in its code, which was introduced by Typescript 3)
  2. Also I had to change the target in tsconfig.json to es2015. (otherwise you'll run into class constructors must be invoked with |new| console errors)

Have fun! I hope it helps.

like image 94
platzhersh Avatar answered Apr 25 '23 17:04

platzhersh