obsidian-dataview icon indicating copy to clipboard operation
obsidian-dataview copied to clipboard

dv table displaying due dates doesn't pick up due dates in tasks

Open filmgal opened this issue 2 years ago • 24 comments

What happened?

I have dataview due dates (formatted as (due:: 2022-07-11)) everywhere: frontmatter, tasks, within notes. I discovered today that all due dates within tasks don't appear in my dataview tables that display due dates.

My guess is that it has something to do with inline fields being tied to a note title and tasks being tied to, well, a task I guess.

If this is the way it goes, is there a way to get a list or table of all due dates regardless of where they appear (frontmatter, note, task)?

Example file: due date does not appear in my table

- [ ] this is (due:: 2022-07-11)
- [ ] more tasks

due date does appear

this is (due:: 2022-07-11)
- [ ] more tasks

DQL

table (due.month + "-" + due.day) as "due date"
WHERE (striptime(due) - striptime(date(now)) <= dur(30 days)) and (striptime(due) - striptime(date(now)) >= dur(1 days))
sort due

JS

No response

Dataview Version

0.5.36

Obsidian Version

0.14.15

OS

Windows

filmgal avatar Jul 04 '22 19:07 filmgal

Your idea is correct. When doing tables for tasks, due will be available under file.tasks. You can inspect the metadata in the console to verify.

AB1908 avatar Jul 04 '22 20:07 AB1908

Is there anyway to modify my DQL to include both tasks and anything else?
The idea is to get notification of upcoming due dates - I think most users will not care if they put the due date in a task or in a note; but they will care when they miss a due date because it was a task rather than a note (or vice versa)!

filmgal avatar Jul 04 '22 20:07 filmgal

I think I found it. I can add

or contains(striptime(file.tasks.due), striptime(date(today)))

and it seems to work!

filmgal avatar Jul 04 '22 21:07 filmgal

Very cool! Don't think you need striptime BTW.

AB1908 avatar Jul 04 '22 22:07 AB1908

I'll try without the striptime as you suggest.

I spoke too soon when I said the entire thing worked. It works fine when using contains(striptime(file.tasks.due), striptime(date(tomorrow)) where one could just include the date as today, or tomorrow. But it doesn't work when trying to get upcoming due dates.

This works for due dates not in tasks:

table WHERE due - date(now) <= dur(30 days) and due - date(now) >= dur(1 days) 

but it doesn't work for file.tasks (so I can't add an OR condition because it doesn't work on its own)

table Where file.tasks.due - date(now) <= dur(30 days) and file.tasks.due - date(now) >= dur(1 days) 

filmgal avatar Jul 04 '22 23:07 filmgal

Let me test some stuff out and get back to you. It's been a while since I've done stuff like this.

AB1908 avatar Jul 04 '22 23:07 AB1908

You want to list all pages which have due field somewhere, including in the tasks? Maybe something like

TABLE WHERE
  (due - date(now) <= due(30 days) and due - date(now) >= dur(1 days))
  OR any(map(file.tasks, (t) => t.due - date(now) <= due(30 days) and t.due - date(now) >= dur(1 days)))

It's kind of hard to sort on the task field though... a few more DQL functions for array operations would probably make this easier.

blacksmithgu avatar Jul 04 '22 23:07 blacksmithgu

Thank you for the suggestion. I'll keep noodling to try to make it work. Unfortunately, as is, I get the following error: Dataview: Error: 20220704_195945

filmgal avatar Jul 05 '22 00:07 filmgal

I should say I hope you don't think I'm being a pain for something that only I can use. I really do think people use due dates all the time and they really can't be bothered to have to remember how they input the due date (i.e., task or within the note, or frontmatter), I think it's a fairly important issue because when inserting due dates in one form or another we tend to think they will appear when necessary, and one doesn't want to forget a Doctor's appointment, for example, because it was entered as a task rather than within a note.

Just saying that this particular issue is not a small one. But, maybe I'm wrong. Maybe people are fastidious about how they enter due dates (tasks only, notes only, etc) and I'm the outlier, entering stuff willy-nilly!

filmgal avatar Jul 05 '22 00:07 filmgal

There's a typo in the blacksmithgu query ( 🙂 ) easy to identify: dur() function instead of due():

TABLE
WHERE
  (due - date(now) <= dur(30 days) and due - date(now) >= dur(1 days))
  OR any(map(file.tasks, (t) => t.due - date(now) <= dur(30 days) and t.due - date(now) >= dur(1 days)))

mnvwvnm avatar Jul 05 '22 21:07 mnvwvnm

@mnvwvnm Ah good catch! Thanks.

filmgal avatar Jul 05 '22 21:07 filmgal

Alas... it doesnt pick up tasks with due dates.

image image

filmgal avatar Jul 06 '22 01:07 filmgal

It's no biggie. I'll just create a query for tasks right under my query for notes.

filmgal avatar Jul 06 '22 03:07 filmgal

(need @blacksmithgu confirmation)

I think the code fails because the map() part related with file.tasks can't deal with the "null - date" in tasks with no due date. image Maybe with a filter to consider only the tasks with due date:

TABLE
WHERE
  (due - date(now) <= dur(30 days) and due - date(now) >= dur(1 days)) OR
  any(map(filter(file.tasks, (t) => t.due), (k) => k.due - date(now) <= dur(30 days) AND k.due - date(now) >= dur(1 days)))

mnvwvnm avatar Jul 06 '22 08:07 mnvwvnm

Good thinking. Alas, it still doesn't pick up the tasks with due dates in them.

filmgal avatar Jul 06 '22 16:07 filmgal

But you want to see where they're (the notes) or you want to see the tasks (the task text)?

mnvwvnm avatar Jul 06 '22 16:07 mnvwvnm

I would prefer displaying the tasks (the picture is two separate queries), but the filenames would work as well... but the code you suggested doesn't display either; it just displays the due dates in notes. I did manage to create a query that included the tasks filenames at one point in my testing, but I think it errorred out when there were no tasks that fit the bill, as per your 'filter' suggestion. I'll go through my tests to see if I can find it.

image

filmgal avatar Jul 06 '22 16:07 filmgal

Ok, adding this to my regular "due tomorrow" query for notes includes tasks (their filenames):

or contains(striptime(file.tasks.due), date(tomorrow))

But that uses "contains". For an "upcoming" query, I can't use "contains" and that's what got me into trouble.

filmgal avatar Jul 06 '22 16:07 filmgal

My suggestion: create two queries. For example:

## Projects: next 30 days

```dataview
TABLE due
FROM "your-folder-path"
WHERE (due - date(now) <= dur(30 days) and due - date(now) >= dur(1 days))
```

## Tasks: next 30 days

```dataview
TABLE T.text AS Tasks, T.due AS "Due date"
FROM "your-folder-path"
FLATTEN file.tasks as T
WHERE (T.due - date(now) <= dur(30 days) AND T.due - date(now) >= dur(1 days))
```

mnvwvnm avatar Jul 06 '22 18:07 mnvwvnm

Yeah, that's what I doing now. My only issue, really, is that there may be others who think (like I did) that looking for a due date means looking for ALL due dates. Users might not know they need separate queries for the different formats, and may miss important due dates because of it. I suppose one could just stick to one format, but dataview is so damned convenient allowing us to stick in due dates all over the place no matter where we are in our vault ;-)

filmgal avatar Jul 06 '22 18:07 filmgal

Hey @filmgal , do you think it would help if we add a hint to the documentation that task-leveled metadata are not propagated to page level?

s-blu avatar Dec 16 '22 19:12 s-blu

Hey @filmgal , do you think it would help if we add a hint to the documentation that task-leveled metadata are not propagated to page level?

@s-blu, yeah. Although more people might understand what that means if you were to spell it out: due dates within tasks and due dates everywhere else each require their own query; i.e., no single query will give you due dates in both places. (or something like that)

filmgal avatar Dec 16 '22 19:12 filmgal

Hey, thanks for you feedback!

To be precise you can query that in one query:

TABLE duedat, map(file.tasks, (x) => x.duedat)
WHERE duedat OR any(map(file.tasks, (x) => x.duedat))

grafik

But that is, of course, not very intuitive. There's a good reason that task meta data does not get written to the page though: Tasks inherit everything from their page, so when task fields would be saved on the page, too, it would mean every task gets every field value of all the other tasks in the file, too - making it impossible to search for only these tasks that are i.e. due < date(today).

I'll add this to the documentation board and look for a good place to add a appropiate hint to this, as soon as the new documentation is live.

By the way: You could do something like this if you want to use either the duedate (duedat here) on the page, if available, or the earliest duedate found on a TASK.

```dataview
TABLE due
FLATTEN default(duedat, min(map(file.tasks, (x) => x.duedat))) AS due
WHERE due AND due < date(today)
```

s-blu avatar Dec 16 '22 19:12 s-blu

Is this completed with the addition of the documentation on https://github.com/blacksmithgu/obsidian-dataview/commit/b26465af61100b98c77ac0fa469738ab133574fe where it states that nowadays all page fields are inherited into the task?

holroy avatar Feb 03 '24 15:02 holroy