Master_T
Master_T

Reputation: 7913

Javascript: waiting for dynamically loaded script to be ready

I'm using the following code to load a script dynamically in an html page (since I don't know the URL before serving the page):

let script = document.createElement('script');
script.src = 'https://foo/bar/myscript.js';
script.async = false;
script.defer = false;
document.head.appendChild(script);

//Try to use a global function defined in the script:
myFun(); //This raises "undefined" error

following the suggestion here: https://stackoverflow.com/a/7308984/300741 I set the async and defer attributes to false, to be sure that the script loads before I try to use it. But as you can see from the comment in the last line of code, this is not working.

What am I missing here? Note that if I use setTimeout() to wait a bit before calling myFun() it works as expected, so it's definitely an async/deferred loading problem... but how do I fix it? (using Chrome by the way)

Upvotes: 3

Views: 3751

Answers (2)

Lajos Arpad
Lajos Arpad

Reputation: 76591

Let's try to understand what happens. Your Javascript code tries to load a file from the server. File loading is not a quick operation, especially in the case when the client computer, running the web-browser is far away from the server and the request has to go through a various number of computers. Your Javascript code does not wait for the script. It instead runs in continuation and the script will be loaded when it was successfully downloaded. You can therefore use a callback which runs on load, like this:

let script = document.createElement('script');
script.src = 'https://foo/bar/myscript.js';
script.async = false;
script.defer = false;
document.head.appendChild(script);

script.onload = function() {
    myFun();
};

This will make sure that the script is being loaded before your code which was meant to be executed after the script loaded is being executed.

Upvotes: 1

void
void

Reputation: 36703

You can call the function on scripts onload event

let script = document.createElement('script');
script.async = false;
script.defer = false;
document.head.appendChild(script);

script.onload = function(){
  // script is loaded
  myFun();
}

script.src = 'https://foo/bar/myscript.js';

Upvotes: 3

Related Questions