Build a Cash Register Project - Global variables not recognised by test

Tell us what’s happening:

My global variables price and cid aren’t recognised by the tests, even though they are the exact same as provided as the “starter code”.

Both “You should have a global variable called price.” and “You should have a global variable called cid.” fails.

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Cash Register</title>
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Smooch+Sans:wght@100..900&display=swap"
      rel="stylesheet"
    />
    <link rel="stylesheet" href="styles.css" />
    
  </head>
  <body>
    <main>
      <section class="countertop">
        <h1>FCC CASH REGISTER</h1>
        <p class="total-price" id="total-price"></p>

        <div class="inputs">
          <label for="cash">
            Enter cash amount <span class="nowrap">from customer:</span>
          </label>
          <div>
            <input id="cash" type="number" />
            <button id="purchase-btn">Pay</button>
          </div>
        </div>
      </section>
      <div class="outputEl">
        <div class="change-due" id="change-due"></div>
        <h2>Cash in register:</h2>
        <ul id="in-register"></ul>
      </div>
    </main>
    <script type="module" src="script.js"></script>
  </body>
</html>

/* file: script.js */
let price = 1.87;
let cid = [
  ['PENNY', 1.01],
  ['NICKEL', 2.05],
  ['DIME', 3.1],
  ['QUARTER', 4.25],
  ['ONE', 90],
  ['FIVE', 55],
  ['TEN', 20],
  ['TWENTY', 60],
  ['ONE HUNDRED', 100]
];
const purchaseBtn = document.getElementById("purchase-btn");
const paymentInput = document.getElementById("cash");
const change = document.getElementById("change-due");
const inRegister = document.getElementById("in-register");
const totalPrice = document.getElementById("total-price");
let cashToCustomer = {};

totalPrice.innerText = "Price: $" + price.toFixed(2);

const registerTotalCash = getRegisterTotal(cid);

const unitValues = [0.01, 0.05, 0.1, 0.25, 1.0, 5.0, 10.0, 20.0, 100];

function getRegisterTotal(register) {
  let total = 0;
  register.forEach((item) => {
    total += item[1];
  });
  return total;
}

function displayCid() {
  inRegister.innerHTML = "";
  cid.forEach((item) => {
    const li = document.createElement("li");
    li.textContent = JSON.stringify(item)
      .replace(/[\[\]"]/g, "")
      .replace(/(?<!Y),/, "S: ")
      .replace(/Y(?=,),/, "IES: ")
      .replace(/\b\d+(\.\d{1,2})?\b/, "$$$&");
    inRegister.append(li);
  });
  const li = document.createElement("li");
  li.textContent = "TOTAL: $" + registerTotalCash.toFixed(2);
  inRegister.append(li);
}

function countOutChange(pay, change) {
  const availableChange = [...change];
  const availableChangeTotal = getRegisterTotal(availableChange);
  let payBack = 0;
  let leftToPay = Math.round((pay - price - payBack) * 100) / 100;
  let count = 0;
  let potentialCashToCustomer = {};

  if (leftToPay > 0 && availableChangeTotal > 0) {
    for (let i = 8; i >= 0; i--) {
      while (availableChange[i][1] > 0 && leftToPay >= unitValues[i]) {
        availableChange[i][1] -= unitValues[i];
        payBack += unitValues[i];
        count += unitValues[i];
        leftToPay = Math.round((pay - price - payBack) * 100) / 100;
        // Each while loop moves the value of the coin/bill to from the cid-map the change to be payed
      }
      if (count > 0) {
        potentialCashToCustomer[availableChange[i][0]] =
          Math.round(count * 100) / 100;
        // Sets the coin or bill name as key with the total value of the type after each while-loop
      }
      count = 0;
    }
    //The for-loop goes through the cid-map backwards so to start with the highest bill and its value
  }
  if (leftToPay > 0) {
    return false;
  } else {
    change = availableChange;
    cashToCustomer = potentialCashToCustomer;
    return true;
  }
}

function checkSufficientTotal(payment) {
  if (payment) {
    if (payment < price) {
      change.innerText = "Status: INSUFFICIENT_FUNDS";
      alert("Customer does not have enough money to purchase the item");
      return false;
    } else if (payment == price) {
      change.innerText = "Status: CLOSED";
      alert("No change due - customer paid with exact cash");
      return false;
    } else if (payment - price > registerTotalCash) {
      change.innerText = "Status: INSUFFICIENT_FUNDS";
      alert("Register total is not enough");
      return false;
    } else {
      return true;
    }
  } else {
    alert("Please enter a value");
    return false;
  }
}

function putCashOnTable() {
  change.innerText = "";
  const p = document.createElement("p");
  p.innerText = "Status: OPEN";
  p.classList.add("bold");
  change.append(p);
  for (const coin in cashToCustomer) {
    const p = document.createElement("p");
    p.innerText = `${coin}: $${cashToCustomer[coin]}`;
    p.style.fontFamily = '"Smooch Sans", serif';
    change.append(p);
  }
}

function acceptCashInput() {
  let payBack = checkSufficientTotal(paymentInput.value);
  if (payBack) {
    cashToCustomer = {};
    if (countOutChange(paymentInput.value, cid)) {
      putCashOnTable();
    } else {
      change.innerText = "Status: INSUFFICIENT_FUNDS";
      alert("Not enough cash in register");
    }
  }
  displayCid();
}

paymentInput.addEventListener("keyup", (event) => {
  if (event.key === "Enter") {
    acceptCashInput();
  }
});

purchaseBtn.addEventListener("click", acceptCashInput);

displayCid();

/* file: styles.css */

Your browser information:

User Agent is: Mozilla/5.0 (X11; Linux x86_64; rv:134.0) Gecko/20100101 Firefox/134.0

Challenge Information:

Build a Cash Register Project - Build a Cash Register

The problem was that I couldn’t use type=“module” for the script tag. (I usually put type=module let me put the script tag in head, removes the need for “defer” and also puts the JS in strict mode as default.) I didn’t realise that it wasn’t enough for FCC to put the script tag in the body element, but also to remove type="module.