Reputation: 1
i have a problem when i am trying to load an external js and run a function inside once the script tag is created. In myFile.js code i have this code :
function loadMyScript() {
return new Promise(function (resolve, reject) {
var s;
s = document.createElement("script");
s.defer = true;
s.id = "test";
s.src =
"myUrl/externalfile.min.js";
s.onload = resolve;
s.onerror = reject;
document.head.appendChild(s);
});
}
In the same file i try to call loadMyScript, and i would like a new object to be created from the code of my external js :myUrl/externalfile.min.js
async function testMethod(button, objet) {
//new myObjet(button, objet) will be called in myUrl/externalfile.min.js
return this.loadMyScript().then(() => {
console.log('Buildin MyObject');
return new MyObjet(button, objet);
});
}
in my generated html i see this. Here my method loadMyScript create correctly the html element in the :
<script defer="" id="test" src="myUrl/externalfile.min.js"></script>
The issue is that the code I wrote in .then(...) doesn't seem to be executed => The MyObject is not created.
While when I insert the <script> line manually in the html head, everything seems to work correctly
Any advice?
Upvotes: 0
Views: 608
Reputation: 1470
Whenever you run testMethod
, you are actually returning a Promise
which means you should use .then
on it (or await
if your function is async).
Take a look at this example where an external script named js.js
is loaded:
js.js
in the same folder as this snippet (once saved on your local computer)function loadMyScript() {
return new Promise(function (resolve, reject) {
let s = document.createElement("script");
s.src = "js.js";
s.onload = resolve;
s.onerror = reject;
document.head.appendChild(s);
});
};
async function testMethod() {
return loadMyScript().then(() => func(50), (e) => console.log("Error:", e));
};
function RUN_THIS() {
testMethod().then(res => {
if(!res) return;
alert("Loaded script, executed function. The external function returned: " + res);
});
};
To make the code more readable, I have used await
below:
function loadMyScript() {
return new Promise(function (resolve, reject) {
let s = document.createElement("script");
s.onload = resolve;
s.onerror = reject;
s.src = "js.js";
document.head.appendChild(s);
});
};
async function testMethod() {
const result = await loadMyScript();
// Now perform checks using "result";
return func(50);
};
async function RUN_THIS() {
const result = await testMethod()
if(!result) return false;
console.log("Loaded script, executed function. The external function returned:", result);
};
Here, func
is the function or method which is defined in the external script you are trying to load.
Upvotes: 0
Reputation: 44698
Using onload
and onerror
aren't generally considered "best practice" anymore - you could instead attach event listeners to your created element:
function loadMyScript() {
return new Promise(function(resolve, reject) {
var s = document.createElement("script");
s.defer = true;
s.id = "test";
s.src = "myUrl/externalfile.min.js";
s.addEventListener('load', () => resolve(s), false);
s.addEventListener('error', () => reject(s), false);
document.head.appendChild(s);
});
}
Upvotes: 0
Reputation: 971
To my understanding you want to load JavaScript dynamically, from an external file and call a function of that file directly afterwards.
Why don't you use import()
for that?
Instead of appending a script tag to the DOM, you declare your JS file simply as a module and call it inside your current JS file via the import()
function. It is supported by all major browsers.
export function hello() {
return "Hello, from Module.js";
}
import("./path/to/module.js")
.then((module) => {
console.log(
module.hello()
);
// Do something with the module.
});
You can read a bit more at the MDN Page for imports.
Upvotes: 1