How to use constants (and compare dates) in dataviewjs?

LOL, you know what? After all this back and forth testing with dataviewjs, I found that the tasks plugin provides a somewhat easier way of listing all tasks due on a certain day:

```tasks
not done
due today
```

:rofl:

And the tasks in that list are even editable right there in the list.

Only downside I can see right now is that “done” seems to be define as - [ ], which means that - [/] (see Checklists - Minimal Documentation ) will not show in the above query. But that is probably something the plugin developer can change.

Edit: Actually, this could also be seen as a downside: the query above doesn’t seem to provide a link back to the original context of the task. Sorry, this is not true. Dunno where I was looking. The tasks-plugin even allows you to customize how these backlinks should look.

And: Indentations are lost. See: Support showing tasks as indented · Discussion #60 · obsidian-tasks-group/obsidian-tasks · GitHub

Similar in regular DQL

TASK
WHERE !completed AND due = date(today)

About the ts, you can found it in the console.
Use this inline js query to see the attributes of a specific date:

`$=console.log(dv.date('2022-12-08'))`

Open the console and you’ll see something like this:

1 Like

Seems like the the ts date format was the problem with t.due, because .ts does not have to be specified:

this also works:

const dueTasks = dv.pages().file.tasks
  .where(t => !t.completed)
  .where(t => t.due && t.due == dv.date('today').ts);
if(dueTasks.length > 0) {
  dv.taskList(dueTasks, false);
}  

This is useful, as it shows how 2022-12-08 is rendered “backstage” by dv.date(). Thank you.

So I wante to see in what way t.due differs from that and I used the same method

`$=console.log(dv.pages("#uniquetag"))`

which gave me this:

Which I’m comparing to this:

I have now stared at this for quite a while and I can’t see any reason why those dates should not match.

What I do see is that both of them are isLuxonDateTime: true and I also see that there is no YYYY-MM-DD version of the date immediately available, only the year, month, and day separately so that ts indeed seems to be the best solution.

But I don’t understand why a direct comparison doesn’t work. :exploding_head:

Based on the fact that this works:

it seems that t.due provides the date in timestamp format by default, while dv.date() has to be told.

But also this makes no sense, because why would the problem only occur when looking for exact matches (==) and not with < ?

tl;dr When comparing for equality in javascript, it checks whether objects are the same, and not whether the value is the same. So for objects, one need to convert them into a number, like with dv.date(today).ts.

This is related to how javascript functions, and when you compare two dates you’re comparing two objects. And when checking for equality between objects, they’ve got to be the same object. See Equality (==) - JavaScript | MDN .

Therefore whenever you need to compare two dates for equality, you need to transform them into a number, and a very easy way to do this is in our environment is to the dv.date('today').ts. Here is an image showing a note describing a completion date (similar to the due date, but easier for me to produce :slight_smile: ) and the dv.date(today).

As can be seen, the base comparison would be between two objects, with the class name “DateTime”, but they are not the same object in memory, and as such an equality operation would fail.

Finally, the reason t.due == dv.date(today).ts actually works, is that javascript sees the two values as two different types, and tries to make them comparable. So when dv.date(today).ts is seen as a number, it tries to convert t.due, which is perfectly capable of presenting itself as a number, which happens to be the .ts value.

2 Likes

Thank you for restoring order in the world for me (or rather: making me see it).

I am also drawing a lesson for my own thinking: it should have been possible for me to at least come closer to that explanation. If js is comparing two things that apparently are the same but doesn’t see them as the same, it is reasonable to ask something like: well, how does it see them? Or: How does it compare them. And searching for comparison in js might have brought up that explanation.

So why did I not ask those questions? At a general level, I guess it has to do with me not knowing any javascript, plus not even being sure how much of dataviewjs is actual javascript and how much of it is specific to dataviewjs. For example, I think I saw that the date()-function exists in javascript but didn’t quite understand what it meant that in dataviewjs, we use dv.date(). So given that I understood how little I understood, I knew I avoided going down rabbit holes that were likely to keep me busy for a long time and without necessarily giving me a solution to the specific problem at hand. Another way of putting this is: I was looking for relatively quick answers because my objective here was not to learn javascript in general but rather to understand this specific thing.

So, I think that avoidance of rabbit holes contributed to my failure to figure this out, and I don’t blame myself for it. But what is to be learned from this nonetheless is that this is where the value of discussion forums like this one lies: it allows people in situations like mine (trying to understand stuff without going down (too many) rabbit holes) to simply ask for help. The art is in finding the right moment in your thought process to “give up” and ask. While some people would do better if they invested a little more energy into trying to find the answer themselves, I should probably reach out a bit earlier, because the the learning curve seems to be logistic (not logarithmic - you need to invest some thought before seeing some light, and certainly not exponential - there are certainly limits to your learning) and once I’ve past the steep part of the curve, I’m into seriously diminishing returns and this is where help from others can help expand what they call the carrying capacity.

But coming back to the specific problem here and why I didn’t manage to solve it: when I was looking at the representations of the dates in the console, I didn’t really know what I was looking at. For example, I wondered which of the “branches” of this tree were part of the actual date array, and which of them were just calculated for display. In some cases it was obvious when the fields were filled in only when I clicked on them. At some point, I suspected that the date may in fact just be stored as a time stamp and everything else is calculated when needed, but the presence of data about locale and what not made me rule that one out. Also, it would have been even less logical for the comparison to fail if the raw data was just a number.

So this is where I think I could have come up with one of the questions above. In fact, I did sort of ask myself that, but dismissed it as one of those rabbit holes that is unlikely to lead me to the solution I was looking for. So why did I make this (faulty) judgement?

It is actually pretty clear to me: it is because this was about only one specific comparison (==) and not others. I seemed unlikely that this had something to do with how js sees those arrays, because why would it see them differently in different kinds of comparison? So, I didn’t feel a need to understand how js reads that array (or whatever it is) since it would obviously do so in a consistent way.

And I actually still don’t understand why checking for equality is done according to a different logic than than other comparisons. Could you elaborate @holroy? (I found a technical explanation here, but maybe you have a more high level explanation for why this is so or why this makes sense?)

I could go into a length explanation with regards to various programming languages and design philosophy behind the various languages, but that would indeed be diving in at the deep end of the rabbit hole.

I think it suffices to say that javascript is a loosely typed programming languages, and some constructs which are present in other languages are not present in javascript. One of the consequences of this is shown here related to checking for equality.

What is even equality? Just in the simple case of a date, when is a date considered equal to another? When the year, month and day of month is the same? Does the time part need to be equal? Does the hour, minutes, seconds, milliseconds or whatever granularity you choose need to be equal?

And further more that is just looking at the value of a date object. What if you have multiple date object and want to sort them or handle them in lists, then you would need to know which object you’re handling, and even though the dv.date(today) and t.due and/or t.completion holds the same date/time value, there are many cases you would need to differentiate between in order to do proper data management.

Like if you have a locally assigned date object in a function, you’d need to allocate somewhere to store it in memory. But since it’s within a function, and that function could be called multiple times, you need to store each object in a separate location. And then when the function ends, you’d need to clean up afterwards. This would require a very stringent memory handling, and thusly not just a value equality.

In short, javascript has decided that for objects they provide the equality comparison to check for objects being identical (and sharing the same memory references (which otherwise is not known in javascript)), and that you use other methods to check for value equality.

Hope this partially helps you understand some of the reasoning, but it’s not an easy subject to handle without getting into a lot of details (which I’m not even sure I as a Master of Computer Science, know the full extent of).

1 Like

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