DataviewJS Snippet Showcase

Could you provide a small data example? I’m rather new to dataview (and Obsidian) and unaware how you could get a ‘term’ property on your pages and how the resulting data structure look like :x

General speaking, dv.pages() return a data array that again has a function flatMap. Maybe you get the wanted result when you use flatMap instead of map?

Also, for debugging purposes, it can be helpful if you assign pages.sort(a => a.term,'asc').map(a => [a.term,a.definition]) to a variable and then add a console.log(variableName) to your query. Hitting shift ctrl I in Obsidian opens the developer console whereas you’ll see your console.log call.
This way you can investigate how your resulting table data looks like and how the data differs when you get a single row per term/definion or one row with multiple term/definitions.

It could look like this then:

const pages = dv.pages().where(b => b.term)
const tableData = pages
		 .sort(a => a.term,'asc')
		 .map(a => [a.term,a.definition]);
console.log('tableData ->', tableData)
dv.table(['Term','definition'], tableData)

Hope that helps! :slight_smile:

1 Like

Hi! I made a DataviewJS snippet that automatically adds people’s birthdays in your daily notes upon creation, if it exists, like so:

It uses the file’s alias, but I added an option in the code to use the file name instead.

Credit goes to @Moonbase59’s code here, I only added small modifications, hope that’s okay!

Here’s the gist with setup and instructions:

6 Likes

This is very useful – thank you for sharing it. I already have a People folder, and in it the individuals have birthDate: in the yaml. Which bits of your template should I change to accommodate this?

Please tell me how can I learn about the obsidian dataviewjs plugin from the beginning. I am from a non-coding background and don’t know javascript. But I am interested in learning this plugin.

If you haven’t already read them, the docs are a great place to start: Dataview

Hi Saari,

Here is a scenario. I am reading a textbook and want to write down a definition. I write:

term:: "Name of Term"
definition::"Definition of Term"

In some notes I have multiple terms and definitions, and that is when they all seem to be placed in the same entry.

Thank you for showing me how to debug.

1 Like

Change all instances in the code from p.birthday to p.birthDate and it should work.

1 Like

YAS! ^this, plez

+1

Hey! Trying to figure out how to do a combination of:

  • Display taskLists with groupByFile = true
  • Group the files of the taskLists by a custom YAML field
  • Filter out files of the taskLists by a custom YAML field

What I thought would work is:

for (let group of dv.pages().where(p => p.category.contains("project") && p.status.contains("active")).groupBy(p => p.kr)) {
	dv.header(3, group.key);
	dv.taskList(group.rows
	.file
	.tasks
	.sort(t => t.completed))
	;
}

It only works if I put something inside dv.pages(), and limit the contains() statement to a single filter, e.g. only .where(p => p.status.contains("active")). The thing is, I don’t have tags on the pages I’m filtering on (only YAML fields), and I’d prefer to filter with contains() statements on YAML than by adding tags.

My files I’m intending to query here look something like this

---
category: project
status: active
kr: [[Fly to mars]]
---
# Project
- [ ] Task

Any suggestions for a fix?

Btw my error message is “Evaluation Error: TypeError: Cannot read property ‘contains’ of undefined”

1 Like

Hi, does anyone know how to use taskList, but have it not include sub-bullet-points located directly underneath the task? For example, I have tasks that are structured like this:

- [ ] Actual task that I want to appear in taskList
    - Example contextual note I included as sub-bullets
    - Note that these are not tasks / sub-tasks since they lack leading brackets
    - However, taskList still displays them and makes the view too busy

I’ve noticed that those sub-bullet records are stored in the data array with a value for real equaling ‘false’. So I tried to filter for only real == true in the where section, but no luck.

dv.taskList (dv.pages('#tag').file.tasks.where(t => !t.completed && t.real)

Its called “Heatmap Calendar”, search for it on the community plugin list in obsidian

Hi,

I got this code from Eleanor Konik.


//get all md files in vault

const files = app.vault.getMarkdownFiles()

//create an array with the filename and lines that include the desired tag

let arr = files.map(async(file) => {

const content = await app.vault.cachedRead(file)

//turn all the content into an array

let lines = await content.split("\n").filter(line => line.includes("- [?]"))

return ["[["+file.name.split(".")[0]+"]]", lines]

})

//resolve the promises and build the table

Promise.all(arr).then(values => {

console.log(values)

//filter out files without "ad-question" and the note with the dataview script

const exists = values.filter(value => value[1][0] && value[0] != "[[dataviewjs-testing]]")

dv.table(["file", "lines"], exists)

})

I am trying to customise it to show me results only from files tagged #learning. So far no luck. I unsuccessfully tried using dv.pages("#learning").

Can somebody help me, please?

Thanks

1 Like

You probably need k.file.name.includes rather than just k.name.includes

Dataview and Dataview JS for real novices.

I have tried to find a couple of tutorials out there but have found that the gap between a simple dataview query and the same in dataview JS is quite big. If you are new to coding and just want that little bit extra that DataviewJS gives you but are not that good at coding it can be a real challenge. So I thougt I write a little about my setup(really task focused right now) and give a code examples. Maybe it can help someone else to bridge the gap… :slight_smile:

I write all my notes in a daily pages. Its a real mix of meeting notes, tasks and just good to know things.

I am trying out a system that I found at Steve Boyds page here: How I Use Daily Notes In Obsidian [Wonkish] - by Stowe Boyd.
Instead of using hashtags for tags I create some of my own with the following structure [ø:: ”tag”] where ”tag” is the group I want for this task. if it is a task formyself i would write
’- [ ] [ø:: me] ”text of what should be done”.
If i have a task with a due date it would look like this:
’- [ ] [ø:: me] [due:: 2022-05-16] ”text of what should be done by this date”
Both of these of course without the ’ at the beginning to make it a task in obsidian.

I also asign some tasks with the tag ”today”.
So for my daily template I want to list all my tasks wit a due date.
Next I want all my task that should be done today.

I started in Dataview and this worked but dataview wants to group everything with a header and that is to me not a good way to present it.
So below is dataview and dataviewjs querys for listing all tasks with duedates that are not completed, sorted ascending.

Dataview query for listing all tasks with a due date that is not completed. Grouped by due date ascending
TASK
WHERE !completed
WHERE due
GROUP BY due
SORT due asc
DataviewJS query for listing all tasks with a due date that is not completed. Sorted ascending but not grouped by anything.
dv.taskList(dv.pages().file.tasks .where(t => !t.completed).where(t => t.due).sort(t => t.due, "asc"), false)

I have noticed that even though I enjoy the system of designing my own tags with the ø:: system it also makes it a bit more complicated when trying to achieve things that most likely is a lot easier if I would have stuck to the original hashtag system. But I like the way it looks. :slight_smile:
I know this is really simple compared to everything here but I found it quite hard to get the Dataviewjs query to do what I wanted. Hopefully someone might have use of it.

3 Likes

So now to my next challenge and question.

So the first part of my daily template is all task with due dates
After this I do tasks that are not completed and I have marked as today group by ”tag” if I have any.
These tasks looks like this in my files: - [ ] [ø:: idag] ”Any thing I want to fokus on today”
Below is the dataview query I have for this and it works as it should but I dont want the grouping behavior of dataview so I turn to DataviewJS

(idag=today in swedish)

Dataview query for tasks marked as today
TASK
WHERE !completed
WHERE ø = "idag"
GROUP BY ø

However, this dataviewJS is not working. I am pretty sure that that is due to me not quite understanding how I can filter on the ”ø” I use as my tags.

DataviewJS query for tasks marked as today
dv.taskList(dv.pages().file.tasks.where(t => !t.completed).where(t => t.ø(”idag”)), false)

Any suggestions would be helpful. :slight_smile:

Replying to myself here. :slight_smile: I really do not get it.

The below code gives me all my task

dv.taskList(dv.pages().file.tasks .where(t=> !t.completed) .where(t=>t.ø), false)

But when I try to filter out only my today(idag) tasks it wont work.

dv.taskList(dv.pages().file.tasks .where(t=> !t.completed) .where(t=>t.ø.includes(”idag”)), false)

What am I doing wrong?

How to skip non-existing notes when querying?

Hi, I just post my question at the Dataview plugin snippet showcase thread. However, after a few attempts, I think DataviewJS might be the way to go. Can anyone provide any tips for a snippet for this? Thanks!

Anyone knows how to skip non-exist note in the FROM statement?

I want to review my bad habit in my weekly note, yet I wasn’t writing journal everyday. As a result, I always get a prompt complaining about dataview could not resolve link during link lookup.

I used to create the notes I missed manually but it gets more and more annoying as my vault is full of empty journal notes now. So, I am wondering if there is a good way to skip the note that doesn’t exist?

Here is the query I wrote.

list
FROM  
	outgoing([[2022-05-16]])
	or outgoing([[2022-05-17]])
	or outgoing([[2022-05-18]])
	or outgoing([[2022-05-19]])
	or outgoing([[2022-05-20]])
	or outgoing([[2022-05-21]])
	or outgoing([[2022-05-22]])
	and #Habit 

Ok, I found a solution. I am not sure however if this is the way it should be done but it works.

dv.taskList(dv.pages().file.tasks
	.where(t => !t.completed)
	.where(t => t.text.includes("ø:: idag")), false)

This gives me all my tasks that I have with the ”tag” today(idag).
It would be nice to know if this is the way I should work with this ”ø:: ” format that I am using(and like) or if there is a better way.

1 Like

Hello Luis,

sorry for my super late answer. Forgot to turn on the forum notifications…

in case you still need help here, I put together this dataviewjs code that at least worked with my dummy data:

```dataviewjs
const flattened = [];
dv.pages()
	.where(b => b.term)
	.map(p => {
		p.term = dv.array(p.term)
		p.definition = dv.array(p.definition)
	
		for (let i = 0; i < p.term.length; i++) {
			flattened.push({term: p.term[i], definition: p.definition[i]})
		}
	});
	
dv.table(['Term','definition'], flattened
		 .sort(a => a.term,'asc')
		 .map(a => [a.term,a.definition]))
```

This code takes all terms and definitions and put them into a flattened map, which you then use to render the table. Mind that this means two things: (a) you lose all other information from the page and cannot “just” append more info to the table without also touching the map function. (b) This only works if you always have the same amount of “terms” and “definition” keys.

7 Likes