Trouble importing a script and receiving an event

Hey all,

I am currently trying to import a script package that fires an event on the window channel. This works perfectly on a raw html page:

const eventName = 'eventNameFromImportedScript';

const onBootstrapped = () => {
  window.removeEventListener(eventName, onBootstrapped);
  console.log("has been bootstrapped");
  });
};
window.addEventListener(eventName, onBootstrapped);

But when I do that on a playcanvas app through the editor, the window event never fires. Does anyone have any thoughts? The script that fires the event is added via the external script panel in the editor.

Are you referring to the launch tab?

1 Like

Yes. Inspecting the app on the launch tab shows the script in the head of the html so I know its being imported. Something is happening somewhere with scope if I had to guess but I’m not sure how to diagnose it. I can’t release publicly what the actual script I’m importing is (its from a work partner) but I could dm it to you if that would help.

My guess off hand that it could be some sort loading order issue? Maybe the event is fired prior to the listener being setup?

Would you be able to put together a basic example that has the same issue and can be shared publicly?

Here is a public example: PlayCanvas 3D HTML5 Game Engine

This is the external script:

const newEvent = new Event('importedScriptEvent');
window.dispatchEvent(newEvent);

This is the local script on the playcanvas project that receives the event:

const eventName = 'importedScriptEvent';
console.log("scriptEnabled");
const onBootstrapped = () => {
  window.removeEventListener(eventName, onBootstrapped);
  console.log("has been bootstrapped");
};
window.addEventListener(eventName, onBootstrapped);

The script logs “scriptEnabled” but not “has been bootstrapped”. I have been able to get this working on a raw html file that can be seen below:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>HTML 5 Boilerplate</title>
    <script src="index.js"></script>
    <script src="https://pcimportbucket.s3.us-east-2.amazonaws.com/importedScript.js"></script>
  </head>
  <body>
  </body>
</html>

Thanks for the help

Works fine when I dispatch the event in the dev console

This would mean either the event is being dispatched before the eventListener has been setup or the PlayCanvas app is not in the same window context (eg, are you iframing the PlayCanvas app?) as the script that is firing the event.

I am not iFraming the app. So is there a way to delay the external script from loading until after the app has loaded? Sounds like that is the solution, but I don’t see an external script in the loading order drop down.

Would it be possible to host somewhere or ZIP a build of what the final app would be? It would be easier to give advice once the structure is more clear on how the final index.html and app is put together

Edit: Sorry, I didn’t realise there was an external script URL in the settings. I will fork to give an example

Example: PlayCanvas 3D HTML5 Game Engine

I’ve removed the external script from the settings and now it’s being added dynamically by load-external-files.js

And made sure that load-external-files.js is after index.js that setups up the event listener

This only works because the code for the event listener is in global scope. If the event listener is going to be setup in a PlayCanvas scripttype, then that changes when you should load the external scripts that fire the event.

This soon to be published event lifecycle should help more: Added PlayCanvas lifecycle diagram by yaustar · Pull Request #374 · playcanvas/developer.playcanvas.com · GitHub

1 Like

Thanks so much that was extremely helpful