Sorting a dv.table not working!

I have the following dataviewjs code that gets birthdates from ‘people’ files and then is supposed to sort them in order of the number of days until their next birthday. It works great, showing the persons name (name of file), Birthday, Days Until Next Birthday, and Age, but it refuses to sort by ‘Days Until Next Birthday’, instead it sorts alphabetically by Name. I disabled all my plugins and snippets thinking something was influencing it, but even with just Dataview enabled, it won’t sort. I’ve been using CoPilot to write the code, and we tried a dozen different ways, including moving the days left column to be first with no success. Any ideas?

```dataviewjs
const pages = dv.pages('"CRM/People"')
  .where(p => p.fileClass == "People" && p.dates && p.dates.length > 0)
  .filter(p => p.dates.some(date => date.includes("Birthday")));

const today = new Date();

const result = pages.map(p => {
  const birthdays = p.dates
    .filter(date => date.includes("Birthday"))
    .map(date => new Date(date.split("|")[0].trim()));

  const calculateDaysUntilNextBirthday = (birthday) => {
    const nextBirthday = new Date(today.getFullYear(), birthday.getMonth(), birthday.getDate());
    if (nextBirthday < today) {
      nextBirthday.setFullYear(today.getFullYear() + 1);
    }
    return Math.ceil((nextBirthday - today) / (1000 * 60 * 60 * 24));
  };

  const nextBirthday = birthdays.reduce((closest, date) => {
    const daysUntil = calculateDaysUntilNextBirthday(date);
    return daysUntil < calculateDaysUntilNextBirthday(closest) ? date : closest;
  }, birthdays[0]);

  const daysUntilNextBirthday = calculateDaysUntilNextBirthday(nextBirthday);
  const age = today.getFullYear() - nextBirthday.getFullYear() - (today < new Date(today.getFullYear(), nextBirthday.getMonth(), nextBirthday.getDate()) ? 1 : 0);

  return {
    name: "[[" + p.file.name + "]]",
    birthday: nextBirthday.toLocaleDateString(),
    daysUntilNextBirthday: daysUntilNextBirthday,
    age: age
  };
}).filter(p => p.birthday);
console.log(result);
const sortedResult = result.sort((a, b) => a.daysUntilNextBirthday - b.daysUntilNextBirthday);

const formattedResult = sortedResult.map(p => [
  p.name,
  p.birthday,
  p.daysUntilNextBirthday,
  p.age
]);

dv.table(["Name", "Birthday", "Days Until Next Birthday", "Age"], formattedResult);
```

Just on the top of my head, before hitting the bed, try to make sure that daysUntilNextBirthday is the number.

const daysUntilNextBirthday = Number(calculateDaysUntilNextBirthday(nextBirthday));

Try to use console.log() after defining const to see what you get out … numbers or strings or …

Sorry, this is just a short reply for now … cheers, Marko :nerd_face:

Thanks for the suggestion, but it is a number, the function uses math to derive it. I tried your suggestion just to be sure, and nothing changed. :frowning:

That is a lot of code, so this might miss the target, but here are two examples of sorting:

dv.pages()
  .sort(p => p.file.size, 'desc')

[1, 3, 6, 9, 5]
  .sort((a, b) => a - b)

The point being that when using a dvArray it should suffice to calculate/lookup which value to sort on for that particular row in your query.

For a normal javascript array you’ll need to a provide a sort function accepting two elements, and return a “compared” version of those two elements.

So in your case, try doing:

 const sortedResult = result.sort( a => a.daysUntilNextBirthday, 'desc'
1 Like

Perfect, @holroy to the rescue as usual! Thanks!

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.