Build a Device Loan Ledger - Build a Device Loan Ledger

Tell us what’s happening:

The listOverdueDevices function checks only for “CheckedOut” status, sorts the returned array by ascending order and works fine when using zero-padded months/days for both today and dueDate, yet those requirements appear as incomplete (#18, 19 and 20). Am I misunderstanding them?

Your code so far

const equipmentLedger = {
  "1": { 
    type: "PC",
    status: "CheckedOut",
    borrower: {
      name: "John Smith",
      email: "john@acme.org" },
    dueDate: "11/30/2025" },
  "2": {
    type: "Laptop",
    status: "CheckedIn",
    borrower: {
      name: "",
      email: "" },
    dueDate: "" },
  "3": {
    type: "Laptop",
    status: "CheckedOut",
    borrower: {
      name: "Jane Doe",
      email: "jane@acme.org" },
    dueDate: "12/10/2024" },
  "4": {
    type: "iPad",
    status: "CheckedIn",
    borrower: {
      name: "",
      email: "" },
    dueDate: "" }
};

function checkoutDevice(ledger, assetTag, borrower) {
  const updatedLedger = structuredClone(ledger);
  if (!Object.hasOwn(ledger, assetTag)) {
    return { ledger: ledger, message: `Device ${assetTag} was not found.`}
    } else if (updatedLedger[assetTag]["status"] === "CheckedOut") {
      return {ledger: ledger, message: `Device ${assetTag} has already been checked out.`}
    } else {
      const { name, email } = borrower;
      updatedLedger[assetTag]["borrower"]["name"] = name;
      updatedLedger[assetTag]["borrower"]["email"] = email;
      updatedLedger[assetTag]["status"] = "CheckedOut";
      return {ledger: updatedLedger, message: `Device ${assetTag} now registered as borrowed by ${updatedLedger[assetTag]["borrower"]["name"]}.`}
    };
};

console.log();

function checkinDevice(ledger, assetTag) {
  const updatedLedger = structuredClone(ledger);
  if (!Object.hasOwn(ledger, assetTag)) {
    return {ledger: ledger, message: `Device ${assetTag} is not in the ledger.`}
  } else {
    updatedLedger[assetTag]["borrower"]["name"] = "";
    updatedLedger[assetTag]["borrower"]["email"] = "";
    updatedLedger[assetTag]["dueDate"] = "";
    updatedLedger[assetTag]["status"] = "CheckedIn";
    return { ledger: updatedLedger, message: `Device ${assetTag} now registered as checked in.`};
  };
}

console.log()

function getFullDate(date) {
  const dateArr = date.split("/");
  const [tmonth, tday, tyear] = dateArr;
  const fullDate = tyear * 10000 + tmonth * 100 + tday * 1;
  return fullDate;
}

function listOverdueDevices(ledger, today) {
  const overdueDevices = [];
  const fullToday = getFullDate(today)
  for (const assetTag in ledger) {
    if (ledger[assetTag].status === "CheckedOut") {
      const fullDueDate = getFullDate(ledger[assetTag].dueDate)
      if (fullDueDate < fullToday) {
        overdueDevices.push({ assetTag, fullDueDate });
      }
    }
  }
  overdueDevices.sort((a,b) => a.fullDueDate - b.fullDueDate);
  const plainOverdueDevices = overdueDevices.map(obj => obj.assetTag)
  return plainOverdueDevices;
};

console.log(listOverdueDevices(equipmentLedger, "01/1/2026"))

function serializeLedger(ledger) {
  const ledgerString = JSON.stringify(ledger);
  return ledgerString;
}

function loadLedger(json) {
  const jsObject = JSON.parse(json);
  return jsObject;
}


Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36

Challenge Information:

Build a Device Loan Ledger - Build a Device Loan Ledger

GitHub Link: freeCodeCamp/curriculum/challenges/english/blocks/lab-device-loan-ledger/69f0a37c3bf194a7c9c62492.md at main · freeCodeCamp/freeCodeCamp · GitHub

Welcome to the forum @viocent,

You should implement a listOverdueDevices(ledger, today) function that takes a ledger object and returns an array of the device objects that are overdue

Is listOverdueDevices returning an array of the device objects as asked?

It looks like you have changed the contents of equipmentLedger in the starting code, which could cause the tests to fail. You may want to add another object to that (for testing) since your dates are not ordering correctly.

Try this:

"5": { type: "Laptop", status: "CheckedOut", borrower: { name: "John Doe", email: "john@acme.org" }, dueDate: "9/2/2025" },

Happy coding

Thank you for the snippet. I tried with the original ledger object by itself and by adding your code but there’s still no difference. The output of my listOverdueDevices is an array containing only tags ([“5”, “3”, “1”] in this case) so I thought maybe returning the full objects might make a difference but the same checks still fail. I’m thinking the for…in loop might be breaking things since it hasn’t been covered at this point in the course so it might not be expected.

Please post your updated code so we can take a look.

That’s not the issue.

Here I removed the const plainOverdueDevices from before and return overdueDevices instead

function listOverdueDevices(ledger, today) {
  const overdueDevices = [];
  const fullToday = getFullDate(today)
  for (const assetTag in ledger) {
    if (ledger[assetTag].status === "CheckedOut") {
      const fullDueDate = getFullDate(ledger[assetTag].dueDate)
      if (fullDueDate < fullToday) {
        overdueDevices.push({ assetTag, fullDueDate });
      }
    }
  }
  overdueDevices.sort((a,b) => a.fullDueDate - b.fullDueDate);
  return overdueDevices;
};

And this is the equipmentLedger I’m using (I tried both the original unmodified and this one)

const equipmentLedger = {
  "1": { type: "PC", status: "CheckedOut", borrower: { name: "John Smith", email: "john@acme.org" }, dueDate: "11/30/2025" },
  "2": { type: "Laptop", status: "CheckedIn", borrower: { name: "", email: "" }, dueDate: "" },
  "3": { type: "Laptop", status: "CheckedOut", borrower: { name: "Jane Doe", email: "jane@acme.org" }, dueDate: "10/31/2025" },
  "4": { type: "iPad", status: "CheckedIn", borrower: { name: "", email: "" }, dueDate: "" },
  "5": { type: "Laptop", status: "CheckedOut", borrower: { name: "John Doe", email: "john@acme.org" }, dueDate: "9/2/2025" }
};

Thanks for the help btw!

It looks like you are not returning the ledger objects for asset tags with a “CheckedOut” status. And when I change your code to do that, the objects aren’t sorting correctly by date.

Ok so I did have to return the entire object, not just the tags. Then I think the problem might be that I’m pushing a new object consisting of only assetTag and dueDate keys (in numbers, so they can be sorted) and it doesn’t include the status key, which is what the program is probably checking for. I’ll try adding that in and see if anything changes.

if (fullDueDate < fullToday) {
        overdueDevices.push({ assetTag, fullDueDate });
      }

Did the instructions say your ledger object should include a reformatted date? Can you think of another way to push the entire ledger object rather than recreating it piece by piece?

Ok I solved it, I passed a shallow copy of the object with the fullDueDate I had calculated previously.

overdueDevices.push({...ledger[assetTag], fullDueDate});

The sort function continued to work.

Thank you so much for the help.