Build a Cash Register Project - Build a Cash Register

Tell us what’s happening:

Can you tell me why I can’t pass these tests? I don’t see problem.



Your code so far

<!DOCTYPE HTML>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Fcc Cash Register Project</title>
    <link rel="stylesheet" href="styles.css">
  </head>
  <body> 
    <main>
    <h1 id="h1-main">Welcome to our Shopping mall</h1>
    <div id="change-due"></div>
    <div class="input-div">
    <label for="cash" id="label">Enter cash from customer:</label>
    <input id="cash" type="number" min="0">
    <button id="purchase-btn">Purchase</button>
    </div>
    <div class="container">
      <div>
      <div id="top">
        <p id="total">Total: $1.87</p>
      </div>
        <div id ="connector"></div>
        </div>
        <div id="top-register">
          <div id="buttons-container">
            <button class="btn"></button>
            <button class="btn"></button>
            <button class="btn"></button> 

            <button class="btn"></button>
            <button class="btn"></button>
            <button class="btn"></button>

            <button class="btn"></button>
            <button class="btn"></button>
            <button class="btn"></button>
          </div>
          <div id="true">
            <p id="fcc-market">fcc Market</p>
            <p id="myName">Fardin Mohammadi</p>
          </div>
          <div id="cash-info"></div>
        </div>
    </div>
    </main>
    <script rel="stylesheet"src="script.js"></script>
  </body>
</html>

let input = document.getElementById("cash");
let btn = document.getElementById("purchase-btn");
let changeDiv = document.getElementById("change-due");
let cashInfo = document.getElementById("cash-info");
let ko = [] 
let item = {}
let status; 
let bazmande = [];

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]
];

let c1d = [
  100,
  20,
  10,
  5,
  1,
  0.25,
  0.1,
  0.05,
  0.01,
];

let c1dName = [
  'ONE HUNDRED',
  'TWENTY',
  'TEN',
  'FIVE',
  'ONE',
  'QUARTER',
  'DIME',
  'NICKEL',
  'PENNY'
]

let numberss = [];


// window.onload = () => {
    
// }

class ShoppingCart {
  constructor(x, y) {
    // this.total = 0
    this.name = x;
    this.price = y; 
    // this.object = {};
    // this.item = {}
      }

    
  addItem(x, y) {
    
    if (this.name == x) {
      // changeDiv.innerHTML = "Status: OPEN"
      if (!document.getElementById(this.name)) {
      const na = document.createElement("p");
      na.textContent = `${this.name}: $${y}`;
      na.id = this.name;
      changeDiv.appendChild(na);
       
      let lo = document.getElementById(this.name + this.name); 
      this.price =parseFloat((this.price - y).toFixed(2)); 
      lo.textContent= `${this.name} $${this.price.toFixed(2)}`
      } else { 
      let na = document.getElementById(this.name);
        
      let lolo = document.getElementById(this.name + this.name);

      // console.log(item[y])
      this.price = parseFloat((this.price - y).toFixed(2));
      y = parseFloat((y * item[y])); 
      // console.log(this.price) 
      lolo.textContent= `${this.name} $${this.price.toFixed(2)}`
      // console.log(lolo.textContent)

      na.textContent = `${this.name}: $${y}`;
      
      // console.log(lolo.textContent) 
      }
    } 
    
  }
  
  
}

const prices =  cid.map((_name, index, names) =>
 new ShoppingCart(names[index][0], names[index][1]));
 
const update = () => {
prices.forEach(({name, price}) => {
      const lo = document.createElement("p");
      lo.id = name + name;
      lo.className = "lo"
      lo.textContent = `${name}: $${price}`
      cashInfo.appendChild(lo)
      // console.log(lo)
    })
}
update();

const createElement = (content) => {
  let lo = document.createElement("p");
  lo.textContent = content;
  changeDiv.appendChild(lo);
  lo.id = "changeDivv"
}
// if (remaining > totalAvailableChange) {
//             const changeDivv = document.getElementById("changeDivv")
//             changeDivv.textContent = "Status: INSUFFICIENT_FUNDS";
//             return
//         }  

function updateArray(arrays) {

console.log(arrays)
arrays.forEach((_number, index, numbers) => {
  numberss.push(numbers[index][1]);
})  

}

   function toBeRunOnce(args)  {
  // some stuff to do
  updateArray(args)
  console.log('toBeRunOnce has completed');
  toBeRunOnce = function() {};
}

const addItem = (value) => {
    let remaining = value;
    // let arrays = [...cid];
    let denominations = [...c1d];
    let denominationNames = [...c1dName];
    createElement("Status: OPEN");
    
    toBeRunOnce(cid);
    
    while (remaining > 0) {
        // Check if the remaining value is greater than the sum of all available denominations
        const totalAvailableChange = parseFloat(numberss.reduce((sum, denomination) => sum + denomination, 0).toFixed(2));
        console.log(totalAvailableChange)
        if (remaining > totalAvailableChange) {
            const changeDivv = document.getElementById("changeDivv")
            changeDivv.textContent = "Status: INSUFFICIENT_FUNDS";
            // console.log(totalAvailableChange)
            return
        } 
         else if (totalAvailableChange == remaining) {
          changeDivv.textContent = "Status: CLOSED";
        }


        


        // Find the closest denomination that is less than or equal to the remaining value
        const closestDenominationIndex = denominations.findIndex((denomination) => denomination <= remaining);

        // If no denomination is found, break out of the loop
        if (closestDenominationIndex === -1) {
            break;
        }

        const closestDenomination = denominations[closestDenominationIndex];
        const denominationName = denominationNames[closestDenominationIndex];
        const pricec = prices.find(({ name }) => name === denominationName);
        const { price } = pricec;

        // If the price is 0, remove the denomination from the arrays
        if (price === 0) {
    denominations.splice(closestDenominationIndex, 1);
    const removedElement = denominationNames.splice(closestDenominationIndex, 1)[0];
    const indexToRemoveFromArrays = Math.abs(cid.length - c1dName.indexOf(removedElement) - 1);  
    console.log(indexToRemoveFromArrays);
    if (indexToRemoveFromArrays >= 0) {
        const lop = cid.splice(indexToRemoveFromArrays, 1);
      // console.log(lop); 
      const lopcompleted= cid.filter((name) => name !== lop);
      // console.log(arrays)
      numberss = [];
      updateArray(lopcompleted)
    } else {
      numberss = [];
      updateArray(cid)    
    }
    
      // console.log(arrays) 
      continue;
} 


        // If the price is greater than or equal to the remaining value
        if (!price - remaining < 0) {
            item[closestDenomination] = (item[closestDenomination] || 0) + 1;
            prices.forEach((price) => price.addItem(denominationName, closestDenomination));
            ko.push(closestDenomination); 
            remaining = parseFloat((remaining - closestDenomination).toFixed(2));
        } else {
            // If the price is less than the remaining value, move to the next denomination
            denominations.splice(closestDenominationIndex, 1);
            denominationNames.splice(closestDenominationIndex, 1);
        }

    }
 
    return rabet();
};
  


const rabet = () => {
  // numberss = []
  ko = [];
  item = {};
} 


const conditions = () => { 
  while (changeDiv.hasChildNodes()) {
  changeDiv.removeChild(changeDiv.firstChild);
} 
  if (!input.value) {
    changeDiv.innerHTML = `<p class="jsP">You forgot your wallet?</p>`
  }else if (input.value < price) { 
    alert("Customer does not have enough money to purchase the item.");
    changeDiv.innerHTML = ""
  }else if (input.value == price) {
    createElement("Status: CLOSED");
    changeDiv.innerHTML = "No change due - customer paid with exact cash";
  }else{
 
    input.value-= price;

    addItem(parseFloat(input.value).toFixed(2));
    // if (input.value > 0) {
      
    // }
  }
  input.value = ""
}
 
btn.addEventListener("click", conditions);
input.addEventListener("keydown", (e)=> {
  if(e.key === "Enter") {
    conditions();
// console.log(cid)
 
  }
})



*, ::before, ::after{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

:root {
  --containerBack-color: #BC1700
}

body {
  background-color: #00A5BC;
}

main {
  text-align: center;
  margin-top: 35px;
  font-style: oblique;
  
}

#h1-main {
  margin-bottom: 18px; 
  font-weight: 800;
  font-family: "Lato", Helvetica, Arial, sans-serif;
}

.jsP {
  /* color: #BC00A5; */
  color: #FF1500;
  margin-bottom: 14px;
  font-size: 19px
}

.input-div {
  display: flex;
  flex-direction: column;
  /* justify-content: center; */
  align-items: center;
  gap: 10px;
  margin-bottom: 65px;
}

#label {
  font-size: 20px;
}

input {
  width: 220px;
  height: 25px;
  padding-left: 8px;
}

#purchase-btn {
  cursor: pointer;
  padding: 4.55px;
  background-color: #47BC00;
  border-radius: 4px;
  border: 1px solid #A5BC00;
  margin-top: -2px;
  font-weight: bold;
  letter-spacing: 0.6px;
}

.container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  margin-left: 20px;
}

#top {
  width: 120px;
  height: 37px;
  background-color: var(--containerBack-color); /* #A5BC00 */
  color: white;
  justify-content: center;
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  text-align: center;
  border-radius: 3px;
  /* position: relative; */
  margin-left: -130px;
}

#total {
  width: 80%;
  height: 70%;
  background-color: black;
  margin: 0 auto;
  color: white;
  text-align: center;
  justify-content: center;
  align-items: center;
  display: flex;
  border-radius: 3px;

}

#connector {
  width: 30px;
  height: 20px;
  background-color: var(--containerBack-color);
  /* position: absolute; */
  /* left: 0 */
  /* top: 0; */
  margin-top: -2px;
  margin-left: -90px;
  border-radius: 1px;
  }

#top-register {
  /* width: 41%; */
  width: 310px;
  height: 250px;
  background-color: var(--containerBack-color);
  display: flex;
  position: relative;

  /* justify-content: space-around; */
}
  
#buttons-container {
  width: 27%;
  margin: 15px 4px;
}

.btn {
  width: 20px;
  height: 20px;
  background-color: #47BC00;
  border: none;
}

/* #for-fun {
  position: absolute;
  /* bottom: 150px; */
/* } */ 

#true {
  width: 90px;
  height: 79px;
  background-color: black;
  position: absolute;
  /* color: white; */
  bottom: 40px;
  border-radius: 5px;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  left: 7.5px;
  /* top: 0; */
}

#fcc-market {
  font: bold 13px Comic Sans MS, Comic Sans, cursive;
  color: #d2ae2d
}

#myName {
  width: 80px;
  font: bold 14.5px Comic Sans MS, Comic Sans, cursive;
  font-style: oblique;
  color: #80a758
}

#cash-info {
  width: 45%;
  height: 90%;
  background-color: #b5dcf2;
  border-radius: 12px 25px;
  justify-content: center;
  align-items: center;
  margin: auto;

}

#cash-info {
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  /* align-items: center; */
  justify-content: center;
  gap: 4.5px

}

/* .lo {  */
  /* align-items: center;
  justify-content: center; */
/*   
} */

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0

Challenge Information:

Build a Cash Register Project - Build a Cash Register


Hi there,

Just put your output messages right into #change-due div.

Don’t put it in the extra #changeDivv paragraph or something like that

Hi Toan, Thank you for you reply.


In example fcc did it too, because of the test rules I shouldn’t do it?

Yeah, that’s probably not the cause. Sorry.

Np toan, I appreciate your feedback, I’ll try first.

This is so strange.

I thought the test will automatically replace price and cid value for each test and don’t depend on hard coded price and cid value.
But it’s seem that’s not the case.

For example, these 2 tests have the same price and #cash value, but different cid:

Test 11:

When price is 19.5, the value in the #cash element is 20, cid is [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]], and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: OPEN QUARTER: $0.5"

Test 14:

When price is 19.5, the value in the #cash element is 20, cid is [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]], and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: INSUFFICIENT_FUNDS"

If we hard-code cid with value on Test 11, then Test 11 passed, Test 14 failed
If we hard-code cid with value on Test 14 then Test 11 failed, Test 14 passed

Something is not right here, but I don’t know what is.

I didn’t check the logic of the code yet but it’s seem alright when testing manually.

Hope someone will help this out.

Exactly toan.
I don’t know the problem is because of my code or it’s the site’s code editor.
Btw I wrote my addItem function with recurstion loop at first, but everytime it gave me inifinite loop error, no matter how much I changed it. and when i copy pasted it in vscode it worked without problems.
I hope I’ll find the solution and move on to next courses.

Can you share your latest code and what issue you are attempting to solve? (In case it is not the same as the first post you made?)

This is my updated code(I deleted the excess) but I didn’t find any solution for that problem yet. that’s still my issue and it’s holding me back to continue.

let input = document.getElementById("cash");
let btn = document.getElementById("purchase-btn");
let changeDiv = document.getElementById("change-due");
let cashInfo = document.getElementById("cash-info");
let ko = [] 
let item = {}
let status; 

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]
];

let c1d = [
  100,
  20,
  10,
  5,
  1,
  0.25,
  0.1,
  0.05,
  0.01,
];

let c1dName = [
  'ONE HUNDRED',
  'TWENTY',
  'TEN',
  'FIVE',
  'ONE',
  'QUARTER',
  'DIME',
  'NICKEL',
  'PENNY'
]

let numberss = [];


class ShoppingCart {
  constructor(x, y) {
    this.name = x;
    this.price = y; 
   
      }

    
  addItem(x, y) {
    
    if (this.name == x) {
      if (!document.getElementById(this.name)) {
      const na = document.createElement("p");
      na.textContent = `${this.name}: $${y}`;
      na.id = this.name;
      changeDiv.appendChild(na);
       
      let lo = document.getElementById(this.name + this.name); 
      this.price =parseFloat((this.price - y).toFixed(2)); 
      lo.textContent= `${this.name} $${this.price.toFixed(2)}`
      } else { 
      let na = document.getElementById(this.name);
        
      let lolo = document.getElementById(this.name + this.name);

      this.price = parseFloat((this.price - y).toFixed(2));
      y = parseFloat((y * item[y])); 
      lolo.textContent= `${this.name} $${this.price.toFixed(2)}`

      na.textContent = `${this.name}: $${y}`;
      
      }
    }  
  }
}

const prices =  cid.map((_name, index, names) =>
 new ShoppingCart(names[index][0], names[index][1]));
 
const update = () => {
prices.forEach(({name, price}) => {
      const lo = document.createElement("p");
      lo.id = name + name;
      lo.className = "lo"
      lo.textContent = `${name}: $${price}`
      cashInfo.appendChild(lo)
    })
}
update();

const createElement = (content) => {
  let lo = document.createElement("p");
  lo.textContent = content;
  changeDiv.appendChild(lo);
  lo.id = "changeDivv"
}

function updateArray(arrays) {

console.log(arrays)
arrays.forEach((_number, index, numbers) => {
  numberss.push(numbers[index][1]);
})  

}

   function toBeRunOnce(args)  {
  updateArray(args)
  console.log('toBeRunOnce has completed');
  toBeRunOnce = function() {};
}

const addItem = (value) => {
    let remaining = value;
    let denominations = [...c1d];
    let denominationNames = [...c1dName];
    createElement("Status: OPEN");
    
    toBeRunOnce(cid);
    
    while (remaining > 0) {
        const totalAvailableChange = parseFloat(numberss.reduce((sum, denomination) => sum + denomination, 0).toFixed(2));
        console.log(totalAvailableChange)
        if (remaining > totalAvailableChange) {
            const changeDivv = document.getElementById("changeDivv")
            changeDivv.textContent = "Status: INSUFFICIENT_FUNDS";
            return
        } 
         else if (totalAvailableChange == remaining) {
          changeDivv.textContent = "Status: CLOSED";
        }

        const closestDenominationIndex = denominations.findIndex((denomination) => denomination <= remaining);

        if (closestDenominationIndex === -1) {
            break;
        }

        const closestDenomination = denominations[closestDenominationIndex];
        const denominationName = denominationNames[closestDenominationIndex];
        const pricec = prices.find(({ name }) => name === denominationName);
        const { price } = pricec;

        if (price === 0) {
    denominations.splice(closestDenominationIndex, 1);
    const removedElement = denominationNames.splice(closestDenominationIndex, 1)[0];
    const indexToRemoveFromArrays = Math.abs(cid.length - c1dName.indexOf(removedElement) - 1);  
    console.log(indexToRemoveFromArrays);
    if (indexToRemoveFromArrays >= 0) {
      const lop = cid.splice(indexToRemoveFromArrays, 1);
      const lopcompleted= cid.filter((name) => name !== lop);
      numberss = [];
      updateArray(lopcompleted)
    } else {
      numberss = [];
      updateArray(cid)    
    }
      continue;
} 

    if (!price - remaining < 0) {
        item[closestDenomination] = (item[closestDenomination] || 0) + 1;
        prices.forEach((price) => price.addItem(denominationName, closestDenomination));
        ko.push(closestDenomination); 
        remaining = parseFloat((remaining - closestDenomination).toFixed(2));
    } else {
        denominations.splice(closestDenominationIndex, 1);
        denominationNames.splice(closestDenominationIndex, 1);
    }

}
 
    return rabet();
};
  


const rabet = () => {
  ko = [];
  item = {};
} 


const conditions = () => { 
  while (changeDiv.hasChildNodes()) {
  changeDiv.removeChild(changeDiv.firstChild);
} 
  if (!input.value) {
    changeDiv.innerHTML = `<p class="jsP">You forgot your wallet?</p>`
  }else if (input.value < price) { 
    alert("Customer does not have enough money to purchase the item.");
    changeDiv.innerHTML = ""
  }else if (input.value == price) {
    createElement("Status: CLOSED");
    changeDiv.innerHTML = "No change due - customer paid with exact cash";
  }else{
    input.value-= price;
    addItem(parseFloat(input.value).toFixed(2));
  }
  input.value = ""
}
 
btn.addEventListener("click", conditions);
input.addEventListener("keydown", (e)=> {
  if(e.key === "Enter") {
    conditions();
  }
})

It is hard to tell without reindenting your code, but it looks like this line is running in the global scope?

You must find all the code that is running in the global scope and move it into functions that are triggered by the purchase button.
This is because the tests do not reload the code when running. They load it once (which runs everything in the global scope exactly once) and then they just update the cid and price and reissue the purchase event.

Edit: also, pls indent your code properly before seeking feedback as some of us are reading on cellphones and the indentation makes things easier to follow. Also I would add comments to the code to explain various functions of major work being done.

Hi again hbar1st.
Sorry I’m late, A few hours after my last reply, my grandmother died and I couldn’t reply back to you.
Today I Updated my code and I did the same thing that you said.
And still don’t know why I can’t pass this course.

Here is my javascript code

let input = document.getElementById("cash");
let btn = document.getElementById("purchase-btn");
let changeDiv = document.getElementById("change-due");
let cashInfo = document.getElementById("cash-info");
let ko = [] 
let item = {}
let status; 
let arre = [];
 
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]
];

let c1d = [
  100,
  20,
  10,
  5,
  1,
  0.25,
  0.1,
  0.05,
  0.01,
];

let c1dName = [
  'ONE HUNDRED',
  'TWENTY',
  'TEN',
  'FIVE',
  'ONE',
  'QUARTER',
  'DIME',
  'NICKEL',
  'PENNY'
]

let numberss = [];

class ShoppingCart {
  constructor(x, y) {
    this.name = x;
    this.price = y; 
  }
    
  addItem(x, y) {
    //x = denominationName found in addItem function
    //y = closestDenomination found in addItem function
    //this.name = cid names
    //this.name = cid.prices
    if (this.name == x) {
      if (!document.getElementById(this.name)) {
      const thisNamePelement = document.createElement("p");
      thisNamePelement.textContent = `${this.name}: $${y}`;
      thisNamePelement.id = this.name;
      changeDiv.appendChild(thisNamePelement);
       
      let changeDueValues = document.getElementById(this.name + this.name); 
      this.price = parseFloat((this.price - y).toFixed(2)); 
      changeDueValues.textContent= `${this.name} $${this.price.toFixed(2)}`
      } else { 
      let thisNamePelement = document.getElementById(this.name);
      let changeDueValues = document.getElementById(this.name + this.name);

      this.price = parseFloat((this.price - y).toFixed(2));
      y = parseFloat((y * item[y]));
      // check the digit number after decimal for test rule
      const decimalCount = num => {
        // Convert to String
        const numStr = String(num);
        // String Contains Decimal
        if (numStr.includes('.')) {
            return numStr.split('.')[1].length;
        };
        // String Does Not Contain Decimal
        return 0;
      }

      changeDueValues.textContent= `${this.name} $${this.price.toFixed(2)}`
      // if the digits its lower than 2, return it and if it's more than 2 use toFixed(2)
      thisNamePelement.textContent = `${this.name}: $${
        decimalCount(y) > 2 ? y.toFixed(2) : y  
      }`;      
      }
    }   
  } 
}

//making cid array part to part into shopping class
const prices =  cid.map((_name, index, names) =>
 new ShoppingCart(names[index][0], names[index][1]));
// cashInfo
 
const update = () => { 
  prices.forEach(({name, price}) => {
    const lo = document.createElement("p");
    lo.id = name + name;
    lo.className = "lo"
    lo.textContent = `${name}: $${price}`
    cashInfo.appendChild(lo);
  });
}
// adding p for subtracted money
const createElement = (content) => {
  let lo = document.createElement("p");
  lo.textContent = content;
  changeDiv.appendChild(lo);
  lo.id = "changeDivv"
}

//pushing prices numbers values into numberss array
const convertToArrofArr = (arrOfObj) => {
    const valuesArray = [];
    const keysArray = [];
    for (let i = 0; i < arrOfObj.length; i++) {
        let currKey = Object.keys(arrOfObj[i]);
        let currValue = Object.values(arrOfObj[i]);
        keysArray.push(currKey);
        valuesArray.push(currValue);
    }
    valuesArray.forEach((_number, index, numbers) => {
    numberss.push(numbers[index][1]);
  });
}

const addItem = (value) => {
  let remaining = value;
  createElement("Status: OPEN");
  numberss = [];
  
  convertToArrofArr(prices);
  
  while (remaining > 0) {
    // Check if the remaining value is greater than the sum of all available denominations
    const totalAvailableChange = parseFloat(numberss.reduce((sum, denomination) => sum + denomination, 0).toFixed(2)); 
    
    if(totalAvailableChange == 0) {
      const changeDivv = document.getElementById("changeDivv")
      changeDivv.textContent = "Status: CLOSED";
      return
    }

    if (remaining > totalAvailableChange) { 
      const changeDivv = document.getElementById("changeDivv")
      changeDivv.textContent = "Status: INSUFFICIENT_FUNDS";
      break;
    } 
    
    
    // Find the closest denomination that is less than or equal to the remaining value
    const closestDenominationIndex = c1d.findIndex((denomination) => denomination <= remaining);
    
    // If no denomination is found, break out of the loop 
    if (closestDenominationIndex === -1) {
      break; 
    }
    // checking totalAvaibleChange lower than closestDenominationIndex
    let arr = [...numberss];

    for (let i = 0; i <= Math.abs(c1d.length - c1dName.indexOf(closestDenominationIndex) - 1); i++) {
      arre.push(arr[i]);
    }
    if (remaining == totalAvailableChange) {
      arr.forEach((arree) => arre.push(arree));
      const changeDivv = document.getElementById("changeDivv")
      changeDivv.textContent = "Status: CLOSED";
    }
    
    if (remaining > [...new Set(arre)].reduce((acc, or) => acc + or, 0) + 1.87) { 
      const changeDivv = document.getElementById("changeDivv");
      changeDivv.textContent = "Status: INSUFFICIENT_FUNDS";
      return;
  };

    //continue
    const closestDenomination = c1d[closestDenominationIndex];
    const denominationName = c1dName[closestDenominationIndex];
    const pricec = prices.find(({ name }) => name === denominationName);
    const { price } = pricec;
    function findIndexInCid(denominationName) {
      return cid.findIndex(([name]) => name === denominationName);
    } 

    // If the price is 0, remove the denomination from the arrays
    if (price === 0) {
      c1d.splice(closestDenominationIndex, 1);
      const removedElement = c1dName.splice(closestDenominationIndex, 1)[0];
      const indexInCid = findIndexInCid(removedElement);
      if (indexInCid >= 0) {
        cid.splice(indexInCid, 1);
      }
      numberss = [];
      convertToArrofArr(prices);
      continue;
    }
    
    // If the price is greater than or equal to the remaining value
    if (!price - remaining < 0) {
      item[closestDenomination] = (item[closestDenomination] || 0) + 1;
      prices.forEach((price) => price.addItem(denominationName, closestDenomination));
      ko.push(closestDenomination); 
      remaining = parseFloat((remaining - closestDenomination).toFixed(2));
    } else {
        // If the price is less than the remaining value, move to the next denomination  
      c1d.splice(closestDenominationIndex, 1); 
      c1dName.splice(closestDenominationIndex, 1); 
    }
  }  
 return rabet();
};
  


const rabet = () => {
  ko = [];
  item = {};
  arre = []
} 


const conditions = () => { 
  while (changeDiv.hasChildNodes()) {
  changeDiv.removeChild(changeDiv.firstChild);
} 
  if (!input.value) {
    changeDiv.innerHTML = `<p class="jsP">You forgot your wallet?</p>`
  }else if (input.value < price) { 
    alert("Customer does not have enough money to purchase the item.");
    changeDiv.innerHTML = ""
  }else if (input.value == price) {
    createElement("Status: CLOSED");
    changeDiv.innerHTML = "No change due - customer paid with exact cash";
  }else{ 
    addItem(parseFloat(input.value-= price).toFixed(2)); 
  }
    input.value = "";
}
 
btn.addEventListener("click", conditions);
input.addEventListener("keydown", (e)=> {
  if(e.key === "Enter") {
    conditions(); 
  }
})
window.onload = update();

This is an example of code in the global scope.
If any of these rely on cid or price then they will not get updated properly during the tests.

Other examples of code in global scope from your code:

Look at each case and determine if it is doing anything important that affects the results or not. If it just there for the way the app looks (it doesn’t affect any calculations or the change-due output) then it can stay in the global scope, otherwise it has to become part of the purchase button’s click event handling function.

I deleted “ko”, “status” and moved “numberss” & “arre” into addItem function (able when purchase button is clicked). But I can’t move Item because it’s for calculations.
do you have any solution? should I use something else Instead of Item?

let input = document.getElementById("cash");
let btn = document.getElementById("purchase-btn");
let changeDiv = document.getElementById("change-due");
let cashInfo = document.getElementById("cash-info");
let item = {}
 
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]
];

let c1d = [
  100,
  20,
  10,
  5,
  1,
  0.25,
  0.1,
  0.05,
  0.01,
];

let c1dName = [
  'ONE HUNDRED',
  'TWENTY',
  'TEN',
  'FIVE',
  'ONE',
  'QUARTER',
  'DIME',
  'NICKEL',
  'PENNY'
]


class ShoppingCart {
  constructor(x, y) {
    this.name = x;
    this.price = y; 
  }
    
  addItem(x, y) {
    //x = denominationName found in addItem function
    //y = closestDenomination found in addItem function
    //this.name = cid names
    //this.name = cid.prices
    if (this.name == x) {
      if (!document.getElementById(this.name)) {
      const thisNamePelement = document.createElement("p");
      thisNamePelement.textContent = `${this.name}: $${y}`;
      thisNamePelement.id = this.name;
      changeDiv.appendChild(thisNamePelement);
       
      let changeDueValues = document.getElementById(this.name + this.name); 
      this.price = parseFloat((this.price - y).toFixed(2)); 
      changeDueValues.textContent= `${this.name} $${this.price.toFixed(2)}`
      } else { 
      let thisNamePelement = document.getElementById(this.name);
      let changeDueValues = document.getElementById(this.name + this.name);

      this.price = parseFloat((this.price - y).toFixed(2));
      y = parseFloat((y * item[y]));
      // check the digit number after decimal for test rule
      const decimalCount = num => {
        // Convert to String
        const numStr = String(num);
        // String Contains Decimal
        if (numStr.includes('.')) {
            return numStr.split('.')[1].length;
        };
        // String Does Not Contain Decimal
        return 0;
      }

      changeDueValues.textContent= `${this.name} $${this.price.toFixed(2)}`
      // if the digits its lower than 2, return it and if it's more than 2 use toFixed(2)
      thisNamePelement.textContent = `${this.name}: $${
        decimalCount(y) > 2 ? y.toFixed(2) : y  
      }`;      
      }
    }   
  } 
}

//making cid array part to part into shopping class
const prices =  cid.map((_name, index, names) =>
 new ShoppingCart(names[index][0], names[index][1]));
// cashInfo
 
const update = () => { 
  prices.forEach(({name, price}) => {
    const lo = document.createElement("p");
    lo.id = name + name;
    lo.className = "lo"
    lo.textContent = `${name}: $${price}`
    cashInfo.appendChild(lo);
  });
}
// adding p for subtracted money
const createElement = (content) => {
  let lo = document.createElement("p");
  lo.textContent = content;
  changeDiv.appendChild(lo);
  lo.id = "changeDivv"
}

const addItem = (value) => {

  let remaining = value;
  createElement("Status: OPEN");
  let numberss = [];
  let arre = [];


//pushing prices numbers values into numberss array  
  const convertToArrofArr = (arrOfObj) => {
    const valuesArray = [];
    const keysArray = [];
    for (let i = 0; i < arrOfObj.length; i++) {
        let currKey = Object.keys(arrOfObj[i]);
        let currValue = Object.values(arrOfObj[i]);
        keysArray.push(currKey);
        valuesArray.push(currValue);
    }
    valuesArray.forEach((_number, index, numbers) => {
    numberss.push(numbers[index][1]);
  });
}
  convertToArrofArr(prices);
  
  while (remaining > 0) {
    // Check if the remaining value is greater than the sum of all available denominations
    
    const totalAvailableChange = parseFloat(numberss.reduce((sum, denomination) => sum + denomination, 0).toFixed(2)); 
    
    if(totalAvailableChange == 0) {
      const changeDivv = document.getElementById("changeDivv")
      changeDivv.textContent = "Status: CLOSED";
      return
    }

    if (remaining > totalAvailableChange) { 
      const changeDivv = document.getElementById("changeDivv")
      changeDivv.textContent = "Status: INSUFFICIENT_FUNDS";
      break;
    } 
    
    
    // Find the closest denomination that is less than or equal to the remaining value
    const closestDenominationIndex = c1d.findIndex((denomination) => denomination <= remaining);
    
    // If no denomination is found, break out of the loop 
    if (closestDenominationIndex === -1) {
      break; 
    }
    // checking totalAvaibleChange lower than closestDenominationIndex
    let arr = [...numberss];

    for (let i = 0; i <= Math.abs(c1d.length - c1dName.indexOf(closestDenominationIndex) - 1); i++) {
      arre.push(arr[i]);
    }
    if (remaining == totalAvailableChange) {
      arr.forEach((arree) => arre.push(arree));
      const changeDivv = document.getElementById("changeDivv")
      changeDivv.textContent = "Status: CLOSED";
    }
    
    if (remaining > [...new Set(arre)].reduce((acc, or) => acc + or, 0) + 1.87) { 
      const changeDivv = document.getElementById("changeDivv");
      changeDivv.textContent = "Status: INSUFFICIENT_FUNDS";
      return;
  };

    //continue
    const closestDenomination = c1d[closestDenominationIndex];
    const denominationName = c1dName[closestDenominationIndex];
    const pricec = prices.find(({ name }) => name === denominationName);
    const { price } = pricec;
    function findIndexInCid(denominationName) {
      return cid.findIndex(([name]) => name === denominationName);
    } 

    // If the price is 0, remove the denomination from the arrays
    if (price === 0) {
      c1d.splice(closestDenominationIndex, 1);
      const removedElement = c1dName.splice(closestDenominationIndex, 1)[0];
      const indexInCid = findIndexInCid(removedElement);
      if (indexInCid >= 0) {
        cid.splice(indexInCid, 1);
      }
      numberss = [];
      convertToArrofArr(prices);
      continue;
    }
    
    // If the price is greater than or equal to the remaining value
    if (!price - remaining < 0) {
      item[closestDenomination] = (item[closestDenomination] || 0) + 1;
      prices.forEach((price) => price.addItem(denominationName, closestDenomination));
      remaining = parseFloat((remaining - closestDenomination).toFixed(2));
    } else {
        // If the price is less than the remaining value, move to the next denomination  
      c1d.splice(closestDenominationIndex, 1); 
      c1dName.splice(closestDenominationIndex, 1); 
    }
  }  
 return rabet();
};
  


const rabet = () => {
  item = {};
} 


const conditions = () => { 
  while (changeDiv.hasChildNodes()) {
  changeDiv.removeChild(changeDiv.firstChild);
} 
  if (!input.value) {
    changeDiv.innerHTML = `<p class="jsP">You forgot your wallet?</p>`
  }else if (input.value < price) { 
    alert("Customer does not have enough money to purchase the item.");
    changeDiv.innerHTML = ""
  }else if (input.value == price) {
    createElement("Status: CLOSED");
    changeDiv.innerHTML = "No change due - customer paid with exact cash";
  }else{ 
    addItem(parseFloat(input.value-= price).toFixed(2)); 
  }
    input.value = "";
}
 
btn.addEventListener("click", conditions);
input.addEventListener("keydown", (e)=> {
  if(e.key === "Enter") {
    conditions(); 
  }
})
window.onload = update();

What is item used for? Why can’t you move it?

Also I see other code still in the global scope and that other code relies on cid so it must move.

prices is the same too

I made “Item” Object to store how much one Item should use to lower the value. and in addItem class I used it. If I move it from global scope, then It will be undefined in addItem class.

which code?

I tried to code like how fcc learned us in previous courses that’s why I used classes and update function.

Move the global code to a local function scope. Then anything that fails you need to refactor. That means that if a class needs something it doesn’t have, then maybe you should give the constructor of that class the thing if needs when you instantiate it.

I cannot write the code for you. I can only advise you where I see a problem.

I have given you a list earlier of other areas in the code that you may need to fix as well so please look at my posts.

I moved everything in local scope and now I just have 2 more failed error. but “prices” doesn’t work when I add 43 two times in input. (when I move it to global scope it works good). help me please I’ve been stuck at this course for so long while my code worked good.

let input = document.getElementById("cash");
let btn = document.getElementById("purchase-btn");
let changeDiv = document.getElementById("change-due");
let cashInfo = document.getElementById("cash-info");
 
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]
];

function processData() {
  let c1d = [
    100,
    20,
    10,
    5,
    1,
    0.25,
    0.1,
    0.05,
    0.01,
  ];

  let c1dName = [
    'ONE HUNDRED',
    'TWENTY',
    'TEN',
    'FIVE',
    'ONE',
    'QUARTER',
    'DIME',
    'NICKEL',
    'PENNY'
  ];

  return { c1d, c1dName };
}

class ShoppingCart {
  constructor(x, y) {
    this.name = x;
    this.price = y; 
    // this.item = {};  
  }
    
  addItem(x, y, item) {
    //x = denominationName found in addItem function
    //y = closestDenomination found in addItem function
    //this.name = cid names
    //this.name = cid.prices
    if (this.name == x) {
      if (!document.getElementById(this.name)) {
      const thisNamePelement = document.createElement("p");
      thisNamePelement.textContent = `${this.name}: $${y}`;
      thisNamePelement.id = this.name;
      changeDiv.appendChild(thisNamePelement);
       
      let changeDueValues = document.getElementById(this.name + this.name); 
      this.price = parseFloat((this.price - y).toFixed(2)); 
      changeDueValues.textContent= `${this.name} $${this.price.toFixed(2)}`
      } else { 
      let thisNamePelement = document.getElementById(this.name);
      let changeDueValues = document.getElementById(this.name + this.name);

      this.price = parseFloat((this.price - y).toFixed(2));
      y = parseFloat((y * item[y]));
      // check the digit number after decimal for test rule
      const decimalCount = num => {
        // Convert to String 
        const numStr = String(num);
        // String Contains Decimal
        if (numStr.includes('.')) {
            return numStr.split('.')[1].length;
        };
        // String Does Not Contain Decimal
        return 0;
      }

      changeDueValues.textContent= `${this.name} $${this.price.toFixed(2)}`
      // if the digits its lower than 2, return it and if it's more than 2 use toFixed(2)
      thisNamePelement.textContent = `${this.name}: $${
        decimalCount(y) > 2 ? y.toFixed(2) : y  
      }`;      
      }
    }   
  } 
}
  
  // cashInfo
const update = () => { 

  const prices =  cid.map((_name, index, names) =>
  new ShoppingCart(names[index][0], names[index][1]));

  prices.forEach(({name, price}) => {
    const lo = document.createElement("p");
    lo.id = name + name;
    lo.className = "lo"
    lo.textContent = `${name}: $${price}`
    cashInfo.appendChild(lo);
  });
}
// adding p for subtracted money 
const createElement = (content) => {
  let lo = document.createElement("p");
  lo.textContent = content;
  changeDiv.appendChild(lo);
  lo.id = "changeDivv"
}

const cart = new ShoppingCart();


const addItem = (value) => {

  let remaining = value;
  createElement("Status: OPEN");
  let numberss = [];
  let arre = [];
  let item = {};

  const { c1d, c1dName } = processData();

  const prices =  cid.map((_name, index, names) =>
  new ShoppingCart(names[index][0], names[index][1]));

//pushing prices numbers values into numberss array  
  const convertToArrofArr = (arrOfObj) => {
    const valuesArray = [];
    const keysArray = [];
    for (let i = 0; i < arrOfObj.length; i++) {
        let currKey = Object.keys(arrOfObj[i]);
        let currValue = Object.values(arrOfObj[i]);
        keysArray.push(currKey);
        valuesArray.push(currValue);
    }
    valuesArray.forEach((_number, index, numbers) => {
    numberss.push(numbers[index][1]);
  });
}

  convertToArrofArr(prices);
  
  while (remaining > 0) {
    // Check if the remaining value is greater than the sum of all available denominations
    
    const totalAvailableChange = parseFloat(numberss.reduce((sum, denomination) => sum + denomination, 0).toFixed(2));
    
    if(totalAvailableChange == 0) {
      const changeDivv = document.getElementById("changeDivv")
      changeDivv.textContent = "Status: CLOSED";
      return
    }

    if (remaining > totalAvailableChange) { 
      const changeDivv = document.getElementById("changeDivv")
      changeDivv.textContent = "Status: INSUFFICIENT_FUNDS";
      break;
    } 
    
    
    // Find the closest denomination that is less than or equal to the remaining value
    const closestDenominationIndex = c1d.findIndex((denomination) => denomination <= remaining);
    
    // If no denomination is found, break out of the loop 
    if (closestDenominationIndex === -1) {
      break; 
    }
    // checking totalAvaibleChange lower than closestDenominationIndex
    let arr = [...numberss];

    for (let i = 0; i <= Math.abs(c1d.length - c1dName.indexOf(closestDenominationIndex) - 1); i++) {
      arre.push(arr[i]);
    }
    if (remaining == totalAvailableChange) {
      arr.forEach((arree) => arre.push(arree));
      const changeDivv = document.getElementById("changeDivv")
      changeDivv.textContent = "Status: CLOSED";
    }
    
    if (remaining > [...new Set(arre)].reduce((acc, or) => acc + or, 0) + 1.87) { 
      const changeDivv = document.getElementById("changeDivv");
      changeDivv.textContent = "Status: INSUFFICIENT_FUNDS";
      return;
  };

    //continue
    const closestDenomination = c1d[closestDenominationIndex];
    const denominationName = c1dName[closestDenominationIndex];
    const pricec = prices.find(({ name }) => name === denominationName);
    const { price } = pricec;
    function findIndexInCid(denominationName) {
      return cid.findIndex(([name]) => name === denominationName);
    } 

    // If the price is 0, remove the denomination from the arrays
    if (price === 0) {
      c1d.splice(closestDenominationIndex, 1);
      const removedElement = c1dName.splice(closestDenominationIndex, 1)[0];
      const indexInCid = findIndexInCid(removedElement);
      if (indexInCid >= 0) {
        cid.splice(indexInCid, 1);
      }
      numberss = [];
      convertToArrofArr(prices);
      continue;
    }
    
    // If the price is greater than or equal to the remaining value
    if (!price - remaining < 0) { 
      item[closestDenomination] = (item[closestDenomination] || 0) + 1;
      prices.forEach((price) => price.addItem(denominationName, closestDenomination, item));
      remaining = parseFloat((remaining - closestDenomination).toFixed(2));
    } else {
        // If the price is less than the remaining value, move to the next denomination  
      c1d.splice(closestDenominationIndex, 1); 
      c1dName.splice(closestDenominationIndex, 1); 
    }
  }  
  item = {}
  numberss = [];
  arre = []
  console.log(item, numberss, arre)
 return rabet();
};
  


const rabet = () => {
  console.log(3424)
} 


const conditions = () => { 
  while (changeDiv.hasChildNodes()) {
  changeDiv.removeChild(changeDiv.firstChild);
}  
  if (!input.value) { 
    changeDiv.innerHTML = `<p class="jsP">You forgot your wallet?</p>`
  }else if (input.value < price) { 
    alert("Customer does not have enough money to purchase the item.");
    changeDiv.innerHTML = ""
  }else if (input.value == price) {
    createElement("Status: CLOSED");
    changeDiv.innerHTML = "No change due - customer paid with exact cash";
  }else{ 
    addItem(parseFloat(input.value-= price).toFixed(2)); 
  }
    input.value = "";
}
 
btn.addEventListener("click", conditions);
input.addEventListener("keydown", (e)=> {
  if(e.key === "Enter") {
    conditions(); 
  }
})
window.onload = update(); 

i don’t understand what you’re trying to say.
(I’m not familiar with your code so you have to show me what you mean otherwise you’re asking me to read your entire code so I can try to make sense of your question)

you still have this line in the global scope.
Can you explain why?
Is it doing something important that affects the calculation? if yes, then it shouldn’t be here.