Understanding DOM object lifecycle

Hi folks. Trying to puzzle out a problem with what I think is DOM object lifecycle. I’ve read through this thread A tour of how the Widget (Virtual DOM) code in Discourse works but it still doesn’t help answer my question, or at least point me in a direction to try and solve my problem. I’m having trouble wrapping my head around it.

I’ve written a very basic plugin as a wrapper for an external service (Rumbletalk chat engine, to be precise) The plugin works as I would like, the chat works, etc, except if you navigate away from the chat to some other part of my site, and then back to chat. I get an error from their included javascript that I’m trying to create a duplicate chat.

The plugin is a simple hbs/widget that creates the following HTML

<div style="height: 500px;">
  <div id="$MY_ID"></div>
  <script src="https://rumbletalk.com/client/?$MY_OTHER_ID"></script>
</div>

And has some log-in javscript as well.

I’m assuming that somewhere in the DOM, the rendered HTML is still around, and when this script tag loads and runs again, it detects it. When I debug in the dev console, I am seeing the error throw from the javascript from the script tag, not the login code.

I’ve reached out to the staff at Rumbletalk, but have had no reply as of yet. Does anyone have a suggestion as to what I can look at next? The only thing I’ve managed to do is add a window.onerror handler and then do a location.reload(). This obviously isn’t a good solution. Is there a way for me to ‘flush’ the chat engine DOM objects when the page goes out of focus?

Thanks for any help

-=Bob

Hey Bob :wave:

Your issue is a bit beyond HTML

<script src="https://rumbletalk.com/client/?$MY_OTHER_ID"></script>

This script runs an IIFE, initializes an instance, and stores the instance in the global scope. The global scope is the same for the entire session in Discourse because it’s a single-page application. You can check that with

console.log(RumbleTalkChat)

After the script loads for the first time. So, RumbleTalkChat["$MY_OTHER_ID"] is what the script is complaining about

if (e.RumbleTalkChat[a.hash]) {
  throw new Error("Trying to create a duplicate chat with code: " + a.hash);
}

You can try to remove that instance before the script loads again with something like this

delete RumbleTalkChat["$MY_OTHER_ID"]

Note that it doesn’t contain the ? character.

That said, you’re probably better off if you figure out why the script is loaded multiple times in the first place. I see that the script has an openChat() method that you can call. So loading the script multiple times might not be necessary.

Unfortunately, you’d need to provide more details about where the embed goes and how you’re adding the markup before we can pinpoint the cause.

4 Likes

Hi Joe
Thanks for the explanation of the IIFE, I assumed it was SOMETHING like that, or, like the title said, was a DOM scoped object. I did see the check

if (e.RumbleTalkChat[a.hash]) {
  throw new Error("Trying to create a duplicate chat with code: " + a.hash);
}

in the module as well. That module is loaded with the rest of the page on the render of the widget. I will see if I can move that possibly into the initializer, and then just render the form.

Thanks again, onward and upwards!

2 Likes