Reputation: 63
I'm trying enter code here in to execute an imported module from a HTML page. I get to see that it's partially getting executed. I need help. My code files are test.html, main.js and say.js. These files are produced below in the same order.
test.html
:
<html>
<head>
<script type="module" src="./main.js"></script>
</head>
<body onload="sayHi('Manish')">
</body>
</html>
main.js
:
import { sayHi } from './say.js';
sayHi('MK');
say.js
:
export function sayHi(user) {
alert('Hello, { $user }');}
Then after this partial execution, it gives an error
Uncaught ReferenceError: sayHi is not defined
at onload (test.html:7)
The picture of the error is as shown below:
This is the error that says sayHi function is not recognized. Why?
What am I doing wrong here?
Upvotes: 3
Views: 4567
Reputation: 63
Basically my objective was to pass some parameter from the HTML script to the main.js file. I have got the required after both of you have given me hints, especially Vikas Saini. The suggestion of adding an event listener in the main.js file helped a lot. Thanks much. I'm posting the corrected and the latest code files for the benefit of ES6 beginners like me.
<html>
<head>
<script type="module" src="./main.js"></script>
</head>
<body>
<input type="text" id="btn-say-hi"label="fill here" placeholder="Fill in here and click"/>
</body>
</html>
import { sayHi } from './say.js';
document.getElementById("btn-say-hi").addEventListener("click", function() {
sayHi(this.value);
});
export function sayHi(user) { alert(`Hello, ${user}`); }
Kindly note: All these files are in the same directory/folder. I could change the text item value and could get the required execution based on my inputs.
Thanks much to T.J. Crowder and a special thanks to Vikas Saini for the code snippet pertaining to adding the event listener. That was a golden suggestion.
Thanks much guys. Regards Manish.
Upvotes: 1
Reputation: 1073968
One of the great things about modules is that top level declarations, etc., in them don't create globals. One of the bad things about onxyz
-attribute-style event handlers is that the functions you call with them have to be globals. Your sayHi
isn't a global, so onload="sayHi('Manish')"
fails because it doesn't have access to sayHi
.
Which is a good thing.
Instead, just call the function from main.js
:
import { sayHi } from './say.js';
sayHi('MK');
sayHi('Manish');
Because module scripts are automatically deferred until the end of HTML processing, you know that won't happen until all the HTML is loaded. This is covered by a great graphic in this section of the spec, duplicated here:
If you want to wait longer, until the load
event (which doesn't fire until all images and such are loaded), use a modern event handler to do that:
import { sayHi } from './say.js';
sayHi('MK');
window.addEventListener("load", () => {
sayHi('Manish');
});
If you need information from the element you hooked the event on, use a traditional function and access the element as this
, or accept the event
parameter and use event.currentTarget
(you can also use event.target
for the element that the event targets, which could be within the element you hooked the event on). So for instance, suppose you have:
<button type="button" data-name="Manish" id="btn-say-hi">
you could have:
import { sayHi } from './say.js';
document.getElementById("btn-say-hi").addEventListener("click", function() {
sayHi(this.getAttribute("data-name"));
});
Also note that as Vikas Saini pointed out your say.js
is using a string literal instead of a template literal (and although he/she didn't mention it, also has the wrong syntax for a substitution), so you'll actually see the text Hello { $user }
instead of seeing Hello MK
or Hello Manish
. Either use a template literal with the correct form of substitution (${user}
, not { $user }
):
export function sayHi(user) {
alert(`Hello, ${user}`);
}
or simple string concatenation:
export function sayHi(user) {
alert("Hello, " + user);
}
Upvotes: 2
Reputation: 485
Classic case of String interpolation
Use
export function sayHi(user) { alert(`Hello, ${user}`);}
Notice ` in place of ' or "
Reference https://campushippo.com/lessons/how-to-do-string-interpolation-with-javascript-7854ef9d
For the Error, bind the window to load
window.addEventListener("load", () => {
sayHi('testing');
});
Upvotes: 1