InGamePanels Template Elements on connectedCallback() error

Hi!

I have a MSFS toolbar panel and it generally works great. My issue is that if I close and reopen the panel then some of the HTML elements on it seem to act oddly, in that they seem not initialized.

For example, I’m in connectedCallback and grab a control to set an initial state like this

<toggle-button id="toggleButton1" class="condensed-interactive" title="Toggly1">
</togglebutton>
const toggleButton1 = document.getElementById('toggleButton1');
toggleButton1.setValue(true);

…will come back (randomly) with ‘setValue is not a function’. Other times it works fine. In my actual code I look for this and guard for it, so this is just a simple example.

Everything about the panel works fine, it’s just this edge case of opening causing some sort of initialize issue. It doesn’t impact all of the elements in the panel, just some of them, like it’s a timing issue? ToggleButtons template seems to fail more than most.

Is there an event other than connectedCallback that indicates the panel is in a ready state for controls to be bound? Is there something I can use to add a listener on a control to see if it is ready?

Thanks for any help/ideas.

To answer my own question, I think it’s related to the DOM loading timing, as Matt hinted at here - ReferenceError: Can't find variable: simvar - #5 by mattnischan_xblms

So the solution is either to retry on a timer, or more nicely, use something like the document.readyState and listen out for when it is ‘complete’ rather than just ‘interactive’ e.g. scripts are all loaded and ready to go (such as the togglebutton template etc). In a normal browser this would be the Windows.load event. Example:

  connectedCallback() {
    super.connectedCallback();

    // will be 'interactive' initially  as scripts etc loading
    console.info("DOM loading?", document.readyState);

    document.onreadystatechange = () => {
      if (document.readyState === "complete") {
        console.info("DOM loaded, complete", document.readyState);
        // Do Stuff
      }
    };

Here’s an idea…

I assuming the error is essentially your getElementById() is returning ‘null’.

Maybe if your panel JS is referenced in the <head> of the html document then move that to just before the closing </body> tag. With the JS in the head (if it is) then the web engine will kick off the load of that JS before the page has loaded.

It’s usual in html/js to either put the piece of JS that kicks off the execution at the end of the page or use the ‘onload’ attribute of the body tag to call some explicit ‘init()’ function that has been coded in your JS. As we don’t have access to the code that calls connectedCallback it’s a bit risky assuming the panel code going to delay calling that method until the rest of the page is loaded…

HTMl/JS instruments (which seem very similar in principle to the toolbar panels) indeed have the instrument JS script imports after the html content.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.