Birthday algorithm with dataviewjs

I use the calendar plugin every day, and for a given day I would like to show a list of my contacts that has birthday that day. I have now tried to pull this off with dataviewjs.

Every contact has a page with the following type of information:

#person
born:: 2000-08-23

If I could compare the month and day of the current file with the “born” attribute of every person, then I guess I would get the desired birthday list.

If I try the following I get an error message. Apparently ‘month’ and ‘day’ doesn’t work for the object ‘p.born’.

let curDate = dv.date(dv.current().file.name);

dv.list(dv.pages("#person")
	.where (p => (p.born.month == curDate.month) && (p.born.day == curDate.day)).file.link)

Do you know how I could fix this code?

I’m not secure about the way how dates work in dvjs (I’m more comfortable in dql), but try this:

let curDate = dv.date(dv.current().file.name);

dv.list(dv.pages("#person")
	.where(p => p.born.toFormat('MM-dd') == dv.date(curDate).toFormat('MM-dd')).file.link)

Thanks for the reply.

I get an error message when I try the formula, as it doesn’t recognise toFormat().

Might there be another alternative or a workaround?

Make sure that Dataview knows that all the dates are dates.

Do you still get the toFormat() error with this version (line breaks are totally optional and just my preference for reading my own code):

const dateFormatString = 'MM-dd';
const curDate = dv.date(dv.current().file.name).toFormat(dateFormatString);

dv.list(
    dv.pages("#person")
    .where(p => dv.date(p.born).toFormat(dateFormatString) === curDate)
    .file.link
);

PS: @mnvwvnm Javascript tip since I know JS is not your favorite: use const instead of let in front of variables whose values you are only setting once. (My variable naming is atrociously verbose though, don’t copy that!)

1 Like

Unfortunately, I get the same error for the toFormat() inside the dv.list().

Evaluation Error: TypeError: Cannot read properties of null (reading 'toFormat')
    at eval (eval at <anonymous> (plugin:dataview), <anonymous>:6:32)
    at Array.filter (<anonymous>)
    at Proxy.where (plugin:dataview:9414:39)
    at eval (eval at <anonymous> (plugin:dataview), <anonymous>:6:6)
    at DataviewInlineApi.eval (plugin:dataview:19667:16)
    at evalInContext (plugin:dataview:19668:7)
    at asyncEvalInContext (plugin:dataview:19678:32)
    at DataviewJSRenderer.render (plugin:dataview:19699:19)
    at DataviewRefreshableRenderer.maybeRefresh (plugin:dataview:19277:22)
    at t.e.tryTrigger (app://obsidian.md/app.js:1:963725)

Thanks.
You’re right: JS isn’t my field at all. The fun thing is: when I do (or trying) something in JS, I always use const; in this case I suggested let following the initial query (because I really don’t know the differences… :slightly_smiling_face:).

You can also try

const curDate = dv.current().file.day;
dv.list(dv.pages("#person").where(p => p.born.toFormat('MM-dd') == curDate.toFormat('MM-dd')).file.link)

About the errors… well, I don’t know if your note titles are in right format!

Thanks for the suggestions. It doesn’t work now either, unfortunately.

The note title for today is 2022-09-06.

Maybe you need to check if born exists in filtered pages. If born = null, I guess the function fails. Try:

const curDate = dv.current().file.day;
dv.list(dv.pages("#person").where(p => p.born && p.born.toFormat('MM-dd') == curDate.toFormat('MM-dd')).file.link)
1 Like

At first this worked, but then it suddenly didn’t again.

Since my setup apparently is a bit buggy, I changed my workflow somewhat and implemented this great Upcoming Birthday Algorithm by @Moonbase59 on a separate page instead.

But thanks for the effort. Really appreciate it.