I am trying to solve the FreeCodeCamp cash register challenge and am meeting all tests apart from tests 18 and 19. I’m confused as to why my code is not meeting those tests (particularly for 19, as the output I am getting seems to match what they want) and would appreciate some advice.
-
When price is 19.5, the value in the #cash element is 20, cid is [[“PENNY”, 0.5], [“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: CLOSED PENNY: $0.5”.
-
When price is less than the value in the #cash element, total cash in drawer cid is equal to change due, and the #purchase-btn element is clicked, the value in the #change-due element should be “Status: CLOSED” with change due in coins and bills sorted in highest to lowest order.
`
// Variables
let price = 19.5;
let cid = [
["PENNY", .5],
["NICKEL", 0],
["DIME", 0],
["QUARTER", 0],
["ONE", 0],
["FIVE", 0],
["TEN", 0],
["TWENTY", 20],
["ONE HUNDRED", 0],
];
// Denomination values
const denomValues = {
PENNY: 0.01,
NICKEL: 0.05,
DIME: 0.1,
QUARTER: 0.25,
ONE: 1,
FIVE: 5,
TEN: 10,
TWENTY: 20,
"ONE HUNDRED": 100,
};
// Helper to handle floating-point precision
function precise(num) {
return parseFloat(num.toFixed(2));
}
// Calculate total cash in the drawer
function sum(arr) {
return arr.reduce((acc, curr) => acc + curr[1], 0);
}
let totalCashInDrawer = sum(cid);
// DOM elements
let changeOwed = document.getElementById("change-due");
let moneyAmount = document.getElementById("cash");
let buyObjects = document.getElementById("purchase-btn");
// Purchase function
function purchaseItem() {
let moneyNumber = parseFloat(moneyAmount.value);
if (isNaN(moneyNumber)) {
alert("Invalid input! Please enter a valid amount.");
changeOwed.innerText = "";
moneyAmount.value = "";
return;
}
let moneyOwedToCustomer = precise(moneyNumber - price);
if (moneyNumber < price) {
changeOwed.innerText = "Status: INSUFFICIENT_FUNDS";
alert("Customer does not have enough money to purchase the item.");
moneyAmount.value = "";
} else if (moneyOwedToCustomer > 0 && totalCashInDrawer < moneyOwedToCustomer) {
changeOwed.innerText = "Status: INSUFFICIENT_FUNDS";
} else if (moneyOwedToCustomer === totalCashInDrawer) {
returnChange(moneyOwedToCustomer);
moneyAmount.value = "";
} else if (moneyOwedToCustomer > 0) {
returnChange(moneyOwedToCustomer);
} else if (moneyNumber === price) {
changeOwed.innerHTML = "No change due - customer paid with exact cash";
moneyAmount.value = "";
}
}
function returnChange(moneyOwedToCustomer) {
let originalCID = JSON.parse(JSON.stringify(cid)); // Deep copy of original CID
let reversedCID = [...cid].reverse();
let finalAmount = { status: "OPEN", change: [] };
reversedCID.forEach(function (arr) {
let denomination = arr[0];
let totalAvailableInDenomination = arr[1];
let denominationValue = denomValues[denomination];
let amountToReturn = 0;
while (moneyOwedToCustomer >= denominationValue && totalAvailableInDenomination > 0) {
moneyOwedToCustomer = precise(moneyOwedToCustomer - denominationValue);
totalAvailableInDenomination = precise(totalAvailableInDenomination - denominationValue);
amountToReturn = precise(amountToReturn + denominationValue);
}
if (amountToReturn > 0) {
finalAmount.change.push([denomination, precise(amountToReturn)]);
}
});
// ✅ Update `cid` before checking "CLOSED"
cid = cid.map(([denomination, total]) => {
let returnedAmount = finalAmount.change.find(([d]) => d === denomination)?.[1] || 0;
return [denomination, precise(total - returnedAmount)];
});
// ✅ Update total cash in drawer
totalCashInDrawer = sum(cid);
// ✅ Correct check for "CLOSED" status
if (totalCashInDrawer === 0) {
finalAmount.status = "CLOSED";
finalAmount.change = reversedCID.filter(([_, amount]) => amount > 0); // Only keep denominations with cash
}
if (moneyOwedToCustomer > 0) {
changeOwed.innerText = "Status: INSUFFICIENT_FUNDS";
} else {
changeOwed.innerText = `Status: ${finalAmount.status} ${finalAmount.change
.map(([denomination, amount]) => `${denomination}: $${amount.toFixed(2)}`)
.join(", ")}`;
}
}
// Event listener
buyObjects.addEventListener("click", purchaseItem);``
I have tried re-writing the closed status code multiple times, including using and removing filters, trying both reversedCID and originalCID, use of variables, moving code blocks etc. Nothing seems to be fixing the issue. The code for test 18 seems almost there.


