Search code examples
javascripttypescriptweb-componentstenciljs

Stencil Component Method definition


I am facing a problem developing a stencil.js web component. I have this error:

(index):28 Uncaught TypeError: comp.hideDataPanel is not a function at HTMLDocument. ((index):28)

I want to integrate my stencil component to a bigger browserify project

Before doing that I am trying the following index.html with the stencil server-dev

    <!DOCTYPE html>
    <html dir="ltr" lang="en">
    <head>
      <meta charset="utf-8">
      <title>Advanced SearchBar</title>
      <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0">
      <meta name="theme-color" content="#16161d">
      <meta name="apple-mobile-web-app-capable" content="yes">

      <meta http-equiv="x-ua-compatible" content="IE=Edge"/>
      <script src="/build/app.js"></script>

      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> <!-- Added -->
      <link rel="manifest" href="/manifest.json">
    </head>
    <body>

      <advanced-searchbar target_url="http://localhost:1234/results" target_id="pdbCode"></advanced-searchbar>
      <script>

        document.addEventListener("DOMContentLoaded", function(event) {
          let comp = document.getElementsByTagName('advanced-searchbar')[0];
          comp.hideDataPanel(); // --> Does not work all the time
        })

        let comp = document.getElementsByTagName('advanced-searchbar')[0];
        comp.addEventListener('clickedOnResult',function(e){
          comp.hideDataPanel(); // --> Works Fine
        })
      </script>
    </body>
    </html>

Methods of my component appear to be unresolved at the DomContentLoaded event while, the same method is resolved at the asychronous user click event. Note that user can use .hideDataPanel() method thanks to @Method() inside typescript code (as shown here: https://stenciljs.com/docs/decorators)

For the purpose of future integration I would like to bind my stencil component method at the startup of my web application. How do i do that ? Shall i wait for a particular event in the page or component lifecycle for component method to be resolved ?

Thank you in advance


Solution

  • Maybe my understanding is wrong and I've never used the event, but according to mdn it sounds like the "DomContentLoaded" event is fired when the HTML DOM has been loaded. I guess that's too early for our webcomponents to be loaded, as they're coming from JS. So you'd need to register on an event that fires when the whole page (including JS) has been loaded which I guess is window.load.

    You could also add an @Event() within the stencil component you're trying to access after it has been loaded and .emit() that event within componentDidLoad(). Stencil events seem to propagate upwards in your dom-tree, so they'll eventually reach document. So you can register and event listener on that event like: document.addEventListener('myCustomStencilEvent', handlerFunction);