Need help on Js modules

Hi there I am trying to implement the export and import modules in my project but when I actually applied it is not working
originally working fine original file
but now I introduce modules using export/import and its not working .
here is my codes

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Java Script Quiz</title>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <div class="wrapper">
      <div class="cm">
        <h1>Community Medicine</h1>
        <br /><br />
        <div class="welcome.text">
          <form
            class="welcome_form"
            name="welcome_form"
            onsubmit="submitForm(event)"
          >
            <input type="text" name="name" />
            <button type="submit">Start Quiz</button>
          </form>
        </div>
        <div>
          <footer>
            <br /><br /><br />
            <p>© 2021 drnareshchauhan</p>
          </footer>
        </div>
      </div>
    </div>
    <!-- //quiz.js -->
    <script type="module" src="./quiz.js"></script>
  </body>
</html>

quiz.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Java Script Quiz</title>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <div class="wrapper">
      <div class="cm">
        <h1>Community Medicine</h1>
        <br /><br />
        <div class="welcome.text">
          <form
            class="welcome_form"
            name="welcome_form"
            onsubmit="submitForm(event)"
          >
            <input type="text" name="name" />
            <button type="submit">Start Quiz</button>
          </form>
        </div>
        <div>
          <footer>
            <br /><br /><br />
            <p>© 2021 drnareshchauhan</p>
          </footer>
        </div>
      </div>
    </div>
    <!-- //quiz.js -->
    <script type="module" src="./quiz.js"></script>
  </body>
</html>

end.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript Quiz</title>
    <!-- //style -->
    <link rel="stylesheet" href="./css/style.css">
</head>
<body>
    <div class="wrapper">
        <div>
            <div><i class="fas fa-award award_icon" ></i></div>
            <h3 class="user_name">Well Done <span class="name"></span>!!</h3>
            <p class="user_points">Your points: <span class="points"></span></p>
            <p class="user_time">Time <span class="time">0 minutes 0 seconds</span></p>
            <a href="./index.html">
                <button>home</button>
                </a>
        </div>
    </div>
    <!-- font awsome -->
    <script src="https://kit.fontawesome.com/2e845a8b3a.js"></script>"></script>
    <!-- user information js -->
    <script src="./modules/userinfo.js"></script>
</body>
</html>

quiz.js

import { questions } from "../dist/modules/quest.js";
window.onload = function () {
  show(0);
};

function submitForm(e) {
  e.preventDefault();
  let name = document.forms["welcome_form"]["name"].value;
  //save user name
  sessionStorage.setItem("name", name);
  location.href = "quiz.html";
}
let question_count = 0;
let points = 0;
function next() {
  let userAnswer = document.querySelector("li.options.active").innerHTML;
  //check answer and give points
  if (userAnswer === questions[question_count].answer) {
    points++;
    sessionStorage.setItem("points", points);
  }
  if (question_count === questions.length - 1) {
    sessionStorage.setItem("time", `${minutes} minutes and ${seconds} seconds`);
    clearInterval(myTime);
    return (location.href = "end.html");
  }

  question_count++;
  show(question_count);
}
function show(count) {
  let question = document.getElementById("questions");
  // question.innerHTML="<h2>" + questions[count].question + "</h2>";
  question.innerHTML = `<h2>Q ${question_count + 1} ${
    questions[count].question
  }</h2>
    <ul class="option_group">
    <li class="options">${questions[count].options[0]}</li>
    <li class="options">${questions[count].options[1]}</li>
    <li class="options">${questions[count].options[2]}</li>
    <li class="options">${questions[count].options[3]}</li>
    </ul>`;
  toggleActive();
}
let toggleActive = () => {
  let options = document.querySelectorAll("li.options");
  for (let i = 0; i < options.length; i++) {
    options[i].onclick = function () {
      for (let j = 0; j < options.length; j++) {
        if (options[j].classList.contains("active")) {
          options[j].classList.remove("active");
        }
      }
      options[i].classList.add("active");
    };
  }
};

modules
quest.js

const questions = [
  {
    id: 1,
    question:
      "Which one of the following does not represent the submerged portion of the iceberg?",
    answer: "Diagnosed cases under treatment",
    options: [
      "Diagnosed cases under treatment",
      "Undiagnosed cases",
      "Pre-symptomatic cases",
      "Carriers sub clinical cases",
    ],
  },
  {
    id: 2,
    question:
      "Which of the following is NOT true regarding pathogenesis of a disease?",
    answer: "Screening is of no use in changing course of disease",
    options: [
      "Screening is of no use in changing course of disease",
      "Tertiary prevention is possible",
      "Entry of organism occurs",
      "Includes subclinical cases",
    ],
  },
  {
    id: 3,
    question: "In Advanced Epidemiological triad, agent is replaced by:",
    answer: "Causative factors",
    options: [
      "Determinant risk factors",
      "Causative bacterium/virus",
      "Causative factors",
      "Determinant factors",
    ],
  },
  {
    id: 4,
    question: "Epidemiological triad are all included except:",
    answer: "Investigator",
    options: ["Host", "Environmental factors", "Agent", "Investigator"],
  },
  {
    id: 5,
    question:
      "Which of the following is an example of Disability limitation in poliomyelitis?",
    answer: "Resting affected limbs in neutral position",
    options: [
      "Reducing occurrence of polio by immunization",
      "Arranging for schooling of child suffering from PRPP",
      "Resting affected limbs in neutral position",
      "Providing calipers for walking",
    ],
  },
];
export { questions };

timer.js

let dt = new Date(new Date().setTime(0))
let time = dt.getTime();
let seconds= Math.floor((time % (100 * 60))/ 1000);
let minutes = Math.floor((time % (1000 * 60 * 60))/ (1000 *60));
let timex = 0
let myTime = setInterval (function() {
    if (seconds <59) {
        seconds++;
    } else{
        minutes++;
        seconds = 0;
    }
    let formattedSec = seconds <10 ? `0${seconds}` : `${seconds}`;
    let formattedMin = minutes <10 ? `0${minutes}` : `${minutes}`;
    document.querySelector('.time').innerHTML= `${formattedMin} : ${formattedSec}`
},1000)

userinfo.js

let name = sessionStorage.getItem("name");
let user_points = sessionStorage.getItem("points");
let user_time = sessionStorage.getItem('time')
document.querySelector(".name").innerHTML = name;
document.querySelector(".points").innerHTML=user_points;
document.querySelector('.time').innerHTML=user_time;

style.css

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
body {
  font-family: Cambria, Cochin, Georgia, Times, "Times New Roman", serif;
}
.wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
  background-color: #341f97;
}
.cm {
  color: white;
  text-align: center;
  font-family: Cambria, Cochin, Georgia, Times, "Times New Roman", serif;
  font-size: 22px;
  padding-bottom: 25px;
  font-style: italic;
}
.welcome.text {
  background-color: white;
  width: 400px;
}
.welcome_form input,
.welcome_form button {
  display: block;
  width: 100%;
}
.welcome_form input {
  margin-bottom: 15px;
  background-color: transparent;
  border: none;
  border-bottom: 2px solid #f0f0f0;
  color: white;
  font-size: 30px;
  text-align: center;
  outline: transparent;
}
.welcome_form button {
  font-size: 22px;
  cursor: pointer;
  padding: 20px 0;
  border: none;
  background-color: white;
  color: #341f97;
  border-radius: 100px;
  transition: 0.4s all;
}
.welcome_form button:hover {
  transform: translateY(-5px);
}
.welcome_form input :focus,
.welcome_form button :focus {
  outline: none;
}
.quiz {
  border-radius: 3px;
  display: grid;
  grid-template-rows: 60px auto;
  width: 800px;
  height: 500px;
  background-color: white;
}
.quiz_header {
  display: flex;
  justify-content: space-between;
  background-color: whitesmoke;
  border-top-left-radius: 3px;
  border-top-right-radius: 3px;
}
.quiz_body {
  padding: 30px;
  background-color: #ecf0f1;
}
.quiz_user {
  display: flex;
  align-items: center;
  padding-left: 30px;
}
.quiz_timer {
  display: flex;
  align-items: center;
  background-color: #341f97;
  color: white;
  padding: 0 30px;
}
.option_group {
  list-style-type: none;
  margin: 30px 0;
}
.options {
  background-color: white;
  width: 800px;
  padding: 15px 20px;
  margin-bottom: 15px;
  border-radius: 100px;
  border: 2px solid transparent;
}
.options:hover {
  cursor: pointer;
  border: 2px solid #341f97;
  color: #341f97;
}
.btn-next {
  background-color: #341f97;
  color: white;
  padding: 15px 35px;
  border: none;
  outline: none;
  border-radius: 100px;
  transition: 0.4s all;
}
.btn-next:hover {
  cursor: pointer;
  background-color: white;
  color: #341f97;
  box-shadow: 0px 0px 10px 1px rgba(0, 0, 0, 0.3);
}
.active {
  background-color: #341f97;
  color: white !important;
}
.award_icon {
  font-size: 300px;
  color: white;
}
button {
  cursor: pointer;
  align-items: center;
  text-align: center;
}
.user_name,
.user_points,
.user_time {
  color: white;
  text-align: center;
  margin-top: 15px;
}
footer {
  font-size: smaller;
  font-family: "Courier New", Courier, monospace;
}

thank you !

Hey mega5255895484!

Wow a lot of info here. So I see that you load in index.html and quiz.html the script quiz.js as a module.
So this means that you want to export something in quiz.js and import it somewhere else, however I see that in quiz.js you do the opposite, you import questions from quest.js.

thanks @usernamegiapreso I want to import question as it contains a answers to the quiz so student should not bale to see by inspecting the web page like we do. But I guess I misunderstood something or what in modules , module !
Can I import questions from quest.js to quiz.js
thanks !

Yes sure. If you think about it, you did it already but in the opposite way.

  • Add quest.js to your html files
  • use the attribute type="module"
  • inside quest.js you’re already exporting questions using the destructuring syntax for module export.
  • inside quiz.js you’re already importing questions using the destructuring syntax for module import.

thank you but
still throwing this error on index html page

Uncaught TypeError: Cannot set property ‘innerHTML’ of null
at show (quiz.js:34)
at window.onload (quiz.js:3)

file modified code re- arranged !

Uncaught TypeError: Cannot set property ‘innerHTML’ of null
at show (quiz.js:34)

This error is not due to modules however, so it’s like another topic.

Because at line 34 of your quiz.js file you’re doing this operation:

  let question = document.getElementById("questions");
  // question.innerHTML="<h2>" + questions[count].question + "</h2>";
  question.innerHTML = `<h2>Q ${question_count + 1} ${
    questions[count].question
  }

My advice about using DOM API is to try it first in browser console to verify that you can actually reach the element that you want to grab.

In your case a quick check on index.html shows that you have not defined any id="questions". So the variable question is undefined and everything applied to it is going to throw an error. :wink:

thank you
but it is already defined in quiz html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Java Script Quiz</title>
    <link rel="stylesheet" href="./style.css">
</head>
<body>
    <div class="wrapper">
        <div class="quiz">
            <div class="quiz_header">
                <div class="quiz_user">
                <h4>Welcome ! <span class="name"></span></h4>
                </div>
                <div class="quiz_timer">
                    <span class="time">00:00</span>
                </div>
                </div>
            <div class="quiz_body">
                <div id="questions">
                    <!-- <H2>Which one of the following does not represent the submerged portion of the iceberg?</H2>
                <ul class="option_group">
                    <li class="option">Diagnosed cases under treatment</li>
                    <li class="option">Undiagnosed cases</li>
                    <li class="option">Pre-symptomatic cases</li>
                    <li class="option">Carriers sub clinical cases</li>
                    <li class="option">Latent & Healthy population</li>
                </ul> -->
                </div>
                <button class="btn-next" onclick="next()">Next Question </button>


            </div>
    </div>
    <script type="module" src="./quiz.js" defer></script>
    <!-- user info js -->
    <script src="./modules/userinfo.js"></script>
    <!-- timer -->
    <script src="./modules/timer.js"></script>
</body>
</html>

Well, not in the quiz.html that you posted in your first post :slight_smile:

But I see now, that maybe you posted two times index.html?

Anyhow, open in the browser the html pages, go to the browser console and check when it gives the error.

Because as I can see, in index.html you load quiz.js, this means that quiz.js will look for the id questions insides the index.html file, will not find it and will throw an error in console.

Thanks a lot @usernamegiapreso
I am able to move from index html to quiz.html with import questions from the modules,
but again in first question it is throwing
quiz.html:32 Uncaught ReferenceError: next is not defined
at HTMLButtonElement.onclick (quiz.html:32)
as you can see below its already defined in quiz.js !!
can’t figure it out ! It is very frustrating !
and sorry to bother you so many times !

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Java Script Quiz</title>
    <link rel="stylesheet" href="./css/style.css">
</head>
<body>
    <div class="wrapper">
        <div class="quiz">
            <div class="quiz_header">
                <div class="quiz_user">
                <h4>Welcome ! <span class="name"></span></h4>
                </div>
                <div class="quiz_timer">
                    <span class="time">00:00</span>
                </div>
                </div>
            <div class="quiz_body">
                <div id="questions">
                    <!-- <H2>Which one of the following does not represent the submerged portion of the iceberg?</H2>
                <ul class="option_group">
                    <li class="option">Diagnosed cases under treatment</li>
                    <li class="option">Undiagnosed cases</li>
                    <li class="option">Pre-symptomatic cases</li>
                    <li class="option">Carriers sub clinical cases</li>
                    <li class="option">Latent & Healthy population</li>
                </ul> -->
                </div>
                <button class="btn-next" onclick="next()">Next Question </button>


            </div>
    </div>
    <script type="module" src="./quiz.js"></script>
    <!-- user info js -->
    <script src="./modules/userinfo.js"></script>
    <!-- timer -->
    <script src="./modules/timer.js"></script>
</body>
</html>
import questions from "./modules/quest.js";
window.onload = function () {
  show(0);
};
let question_count = 0;
let points = 0;
function next() {
  let userAnswer = document.querySelector("li.options.active").innerHTML;
  //check answer and give points
  if (userAnswer === questions[question_count].answer) {
    points++;
    sessionStorage.setItem("points", points);
  }
  if (question_count === questions.length - 1) {
    sessionStorage.setItem("time", `${minutes} minutes and ${seconds} seconds`);
    clearInterval(myTime);
    return (location.href = "end.html");
  }

  question_count++;
  show(question_count);
}
function show(count) {
  let question = document.getElementById("questions");
  // question.innerHTML="<h2>" + questions[count].question + "</h2>";
  question.innerHTML = `<h2>Q ${question_count + 1} ${
    questions[count].question
  }</h2>
    <ul class="option_group">
    <li class="options">${questions[count].options[0]}</li>
    <li class="options">${questions[count].options[1]}</li>
    <li class="options">${questions[count].options[2]}</li>
    <li class="options">${questions[count].options[3]}</li>
    </ul>`;
  toggleActive();
}
let toggleActive = () => {
  let options = document.querySelectorAll("li.options");
  for (let i = 0; i < options.length; i++) {
    options[i].onclick = function () {
      for (let j = 0; j < options.length; j++) {
        if (options[j].classList.contains("active")) {
          options[j].classList.remove("active");
        }
      }
      options[i].classList.add("active");
    };
  }
};

Hey Mega,
No problem I like to help because I like to learn more by doing and solving problems, but for future reference it would be very appreciated to have more comments about what you’re doing in your code, comments about what you’re expecting as a result of something, and also see some console.log() here and there to appreciate that you’re trying to debug it yourself :wink:

In quiz.js you apply the .onclick event listener to options[i], where options is defined as:

let options = document.querySelectorAll("li.options");

So, where are the li elements in your html with class="options"?

I see that inside quiz.js you’re trying to manipulate the html adding code. Generally is a bad idea to use .innerHTML method in prod. However, what you have here is a situation like this:

  • the li.options do not exist until the function show() is called.
  • to show() is passed a parameter and this function manipulates the html.
  • show() is called at windows.onload and then again every time the next() function is called

When is called the function next()?

Inside the quiz.js file never. Only inside the quiz.html file. So we understand a little better about the error it is given to you:

quiz.html:32 Uncaught ReferenceError: next is not defined
at HTMLButtonElement.onclick (quiz.html:32)

<button class="btn-next" onclick="next()">Next Question </button>

Which roughly translates to:
My man, it’s me the browser! I don’t understand what you want me to do at line 32 of your HTML. You told me to call next() whenever somebody clicks on the button, but I don’t know what is next, please explain:slight_smile:

Knowing this the debug becomes easier, just search the web on how to solve similar issue and you’ll find your answer right away. Here’s an example:

The suggestion here basically says:
instead of adding onclick to the html element, just add an event listener inside the JS file that listens for that html element.

If you instead want to force the use of the onclick attribute in HTML: I think that you have to also define, I may be wrong, the callback script inside the html as well using the <script> tag, and not a reference to another script file.

1 Like

Thank U thank U thank U @usernamegiapreso !
I did

<button id="next">Next Question </button>

in quiz html
and

document.getElementById("next").addEventListener("click", next);

in quiz.js
and its perfectly working !
thank you so much at one moment I decided to give up !
now I am able to hide my questions object from the quiz participants ( if what I understood from the module is not wrong)
next I want to learn how to import all those questions from the remote location !
:partying_face:
thank you so much !

1 Like

You’re Mega welcome :wink: