Uncaught ReferenceError: getChecked is not defined using Webpack Bundler

40 views Asked by At

I am using the Webpack bundler to bundle my code, but I get an error saying my getChecked() function is not defined when I run my html page in a browser even though getChecked() is defined and included in the bundle. Uncaught ReferenceError: getChecked is not defined at HTMLButtonElement.onclick ((index):36:71)

Here is how my project is organized: I have one file "getAPIToken.js" which gets an API token through a function called fetchToken(). I have another file "fetchSymptoms.js" which imports fetchToken() and uses it to get the token and display some data. "fetchSymptoms.js" defines the function getChecked(), which executes when a button is clicked. "fetchSymptoms.js" is the entry point to my webpack bundler.

I'm not sure how to make getChecked() be recognized in my browser. How can I make getChecked() be recognized by my browser? Do I need to make sure it's loaded first? I have been super stuck on this for the past two weeks, so any help would be greatly appreciated!

The function getChecked() is defined in fetchSymptoms.js as follows:

 import { fetchToken } from './getAPIToken.js';
    

    fetchToken()
    .then(token => {
        fetchAdultMaleSymptoms(token);
        //fetchSymptoms(token);
    })
    .catch(error => {
        console.error('Error in fetchSymptoms ', error);
    });


function getChecked(){ //displays symptoms from checked checkboxes
    //alert("hello!");
    const checkboxes = document.getElementsByName("symptom"); //items contains nodelist with the checked symptoms
    const array=[]; //create empty array

    for (var i = 0; i < checkboxes.length; i++){ //run through the nodelist
        if (checkboxes[i].type == "checkbox" && checkboxes[i].checked == true){
            if (!array.includes(checkboxes[i].value)){ //if the symptom is not already in array, then push
                array.push(checkboxes[i].value); //add checked items to array
            }
        }
    }

    const jsonArray = JSON.stringify(array); //converts to json string
    sessionStorage.setItem("checked", jsonArray); //will disappear when browser window closed, can use localStorage
}

So the function is defined, and then eventually bundled since fetchSymptoms.js is the entry point. Here is how I use getChecked() in index.html. When run in my browser, index.html gives me errors saying uncaught getChecked() not defined.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="/css/index.css" rel="stylesheet">
    <title>Prognosis Pal</title>
   
    <script src="bundle.js"></script>
    <script src="/js/fetchSymptoms.js"></script>

    <script src="/js/displayCategories.js"></script>
    <!-- <script src="/js/diagnosisSymptoms.js"></script> -->
    
</head>

<body>
    <a href="/you"><button class="you-button">You</button></a>

    <h1>PrognosisPal</h1>

    <div>Select all symptoms that apply</div>

    <div class="symptoms-container">
        <form action="#" id="symptomForm">  
            <div id="ul-container"></div>
            <!-- Symptoms used come from API -->
        
        </form>
    </div>

    <!-- getChecked() gets the values that the user selects for symptom checkboxes-->
    <a href="/diagnosis"><button type="submit" onclick="getChecked()">Diagnosis Me!</button></a>
</body>
</html>

And finally, here is my webpack.config file:

const path = require('path');
//require('dotenv').config({ path: './functions/.env' }); 
const Dotenv = require('dotenv-webpack');


module.exports = {
  entry: './public/js/fetchSymptoms.js', //entry point of your application ./public/js/getAPIToken.js
  output: {
    filename: 'bundle.js', //output bundle filename, where result is going to go
    path: path.resolve('public'), //output directory
  },
  mode: 'none',
  module: {
    rules: [
      {
        test: /\.js$/, // Match JavaScript files
        exclude: /node_modules/, // Exclude node_modules
        use: {
          loader: 'babel-loader', // Use Babel to transpile JavaScript
          options: {
            presets: ['@babel/preset-env'] // Use the preset for modern JavaScript
          }
        }
      }
    ]
  },
  plugins: [
    new Dotenv(),
  ],
  resolve: {
    extensions: ['.js'],
    alias: {
      'crypto-js': path.resolve(__dirname, 'node_modules/crypto-js'),
    },
  },
};

I'm not sure how to make getChecked() be recognized in my browser. Do I need some sort of html plugin included in my webpack.config file? I have been super stuck on this for the past two weeks, so any help would be greatly appreciated!

2

There are 2 answers

0
Delilah On BEST ANSWER

I figured it out-- because I had one entry point for my bundle, I included the script bundle.js in index.html and next.html, which meant when I moved from index.html to next.html, the entire bundle script executed again, which meant my code ran twice.

To solve this issue, I created two entry points, one per each HTML file, and included one script for index.html and a different script for next.html. Here's my new entry point in my webpack config file:

  entry: {
    file1: ['./public/js/fetchSymptoms.js'],
    file2: ['./public/js/diagnosisSymptoms'],
  }
0
Aswindanu Anwar On

This issue is similar to this, can check the solution here

When you run the file over webpack, webpack will try not to litter the global scope and so the function will not be made available globally by default.

If you want the function to be accessible outside the scope of he JS file, you should put it in the global scope.

function uclicked() {
  // do something
}
window.uclicked = uclicked;

Or just:

window.uclicked = function() {
  // do something
}