12

I am struggling to use javascript modules...

I have an html file and a JS module. I have a function defined in the javascript file and I would like to call that function from my HTML page. This is my code

index.html

<html>
<head>
  <script type="module" src="app.js"></script>
</head>
<body>
  <button onclick="greetFromHtml();">greetFromHtml</button>
  <button onclick="greetFromModule()"> greetFromModule</button>
  <script type="text/javascript">
    function greetFromHtml(){
      alert('Hello');
    }
  </script>
</body>
</html>

app.js

function greet(){
  alert('Hello');
}

The greetFromHtml button works fine. When I click the greetFromModule button I get this error: hello is not defined at HTMLButtonElement.onclick

If I remove type="module" from the header, it all works fine, however I need to use modules for some other reasons, so this is not a good solution here.

I have seen several posts saying I need to import/export or use window but I am not sure what to do. Can anyone provide an answer please? Ideally the simplest way to achieve it

See below the reference to some question I have reviewed:

function in my javascript module is not defined

Call functions in a JavaScript from an HTML

How to use code from script with type=module [duplicate]

ES6 Modules: Undefined onclick function after import

EDIT I have tried the following but still getting the same error enter image description here enter image description here enter image description here

EDIT 2 The code in the answer is working. I was just trying to run in locally but I understood you need a server, so if you see the same error, upload the site to server or use a local server.

M4trix Dev
  • 1,828
  • 3
  • 23
  • 48

3 Answers3

30

First of all you have to explicitly export you function:

export function greet() {
  alert("Hello from module");
}

Secondly, a module has it's own scope (this is the whole point of modules) thus you need to add the function to the global scope. So, to do it you have to run a script which imports the function and adds it to the window object:

<script type="module">
  import { greet } from "./app.js";
  window.greetFromModule = greet;
</script>

Now you don't need this part <script type="module" src="app.js"></script>

Alternatively you can create an empty obj and add your modules stuff to it, this is what it would look like:

<html>
  <head></head>
  <body>
    <button onclick="greetFromHtml();">greetFromHtml</button>
    <button onclick="module.greet()">greetFromModule</button>
    <script type="text/javascript">
      function greetFromHtml() {
        alert("Hello");
      }
      const module = {};
    </script>
    <script type="module">
      import { greet } from "./app.js";
      module.greet = greet;
    </script>
  </body>
</html>
mrdarkside
  • 416
  • 4
  • 4
  • Hello mrdarkside many thanks for the response however I am still getting the same error. I have copied and pasted your code but it does not work for me - maybe I am just missing something super basic here... I have added some picture in the question – M4trix Dev Nov 08 '21 at 21:35
  • Hey, try it with a local server, easiest way to do it is to install Live Server extension to VS code. Your browser thinks that your files are from different domains =) – mrdarkside Nov 09 '21 at 22:57
  • Hi Thanks, I have uploaded the website to the server and it is working. Thank you very much – M4trix Dev Nov 11 '21 at 00:54
  • Which way is more proper if you're looking to impress an employer? – Joseph Kreifels II May 19 '22 at 15:13
  • 1
    Why `window.greetFromModule = greet;`? Just `greet()` at that time will execute it – daniel p Sep 16 '22 at 09:54
  • how to call module function inside java script? – Nicholas Jela Jan 01 '23 at 14:12
2

myscript.js

export const sampleFunction=()=>{
alert("Hello I'm sample");

}

index.js

import {sampleFunction} from './myscript.js';
window.sampleFunction=sampleFunction;

index.html

<script type='module' src='./index.js'></script>
<button onclick="sampleFunction()">Click me</button>

In the script tag make script type = 'module' and src = './index.js'. Now it should be working.

BillPlayz
  • 23
  • 4
Ram Kishore
  • 204
  • 3
  • 10
-1

You could also try re-ordering your references in your html document. Put the module that has the function you want to call ahead of the module calling it.

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 22 '23 at 17:44