Dataview: reuse DQL queries?

Hey Craig - very much appreciate the response. Still not working. Maybe my writing it out to you will help me (or you, more likely) solve it… My steps:

  1. Tested a dataview table in a note - to make sure it works.
Table zColor, zShape
From ""
Where file.link = [[]]
  1. Used Visual Studio Code to create a .js file in my ‘035 Scripts’ folder called Case004a. Following is full script.

dv.execute(`

Table zColor, zShape
From “”
Where file.link = [[]]

`);

*Note - I tried with and without ```dataview intro/outro

  1. Included the following in an obsidian note:
dv.view("/035 Scripts/Case004a.js");

*Note: I tried with and without the ‘.js’ at the end

  1. The error (when excluding .js) is:

Evaluation Error: SyntaxError: missing ) after argument list
at new Function ()
at DataviewInlineApi.view (plugin:dataview:19602:24)
at async DataviewJSRenderer.render (plugin:dataview:19705:13)

OK - if you’ve read this far, I appreciate your patience. Perhaps I’m being an idiot and missing something silly. Of course, any ideas are greatly appreciated…thanks, Craig.

1 Like

Just a question: why would you want to embed your DQL queries? Just in order to avoid having to type often used queries anew each time you want to make use of it?

If so, why don’t you just use templates?

Hi @Twita ,

I think you’re really close! I’m not entirely sure what we’re doing differently, so I set up a little mini-vault with two files in it to see if I could re-create your error. It seems to be working for me, so I’m including a screenshot of my setup as well as a zip of the vault (if the forum lets me) so that maybe you can look at it and see where the differences are.

test-vault.zip (642 Bytes)

P.S. I noticed an issue with your js file – the quotes on your From statement are curly quotes, not regular quotes. That won’t work with Dataview. That might just be a copy-paste issue into the forum, but I thought I’d mention it in case your computer is getting too helpful. :slight_smile:

2 Likes

thanks so much - will look into this once I figure out why ALL of my templates now don’t work with update…much appreciated !

Hi @alltagsverstand , great question.

In my use case, I have a team of people that are assigned to different projects. When I’m meeting with a particular person, it’s helpful for me to have a query on their contact page that shows all the projects assigned to them, the next action for each project, and so forth. The query is somewhat complex, using FLATTEN and GROUP BY to display the projects in a way that makes sense for our org.

And as we adapt our processes and workflows to new requirements, I need to make adjustments to the query to show the information I want to have at hand during a meeting. If there was a copy of the query on each contact page, I would have to remember to update each copy of the query for every contact page every time I need to make a change to the query. That’s very tedious and error-prone for someone with a brain like mine. :slight_smile:

Instead, I want to maintain this complex query in one place. That way, when I make changes to it, every contact page automatically shows the updated query without any need to edit the contact pages. I hope that helps!

Craig

P.S. You asked why I can’t use templates. If I include the complex query in a template, I get it on each new page, but I still have the problem of having to edit each page every time I want to update the query.

3 Likes

Here’s another option that lets your reusable query live in a Markdown file, which should only contain your DQL query with no extra JavaScript wrapper and no code block wrapper.

dv.execute(await dv.io.load("Scripts/reusable-query.md"))
6 Likes

This is nice. How do I get this to work with DataviewJS?

Hi @ThurMeijer! If you mean how to use my workaround above with DataviewJS, then I suggest you don’t! :smiley:

Instead, use Dataview’s existing dv.view() mechanism, which is designed for JS script reuse.

I was thinking about the execute / load suggestion @orand mentioned, because I really like the option to be able to see it as a md-file.
Is that also possible with the dv.view-option?

No, I don’t think you can execute md files with dv.view() – it’s very particular on what it will load.

And I think dv.execute() is specific to DQL queries, so I don’t think it will work for JavaScript.

That’s about the extent of my knowledge. Good luck!

You should be able to just replace execute with executeJs

dv.executeJs(await dv.io.load("Scripts/reusable-query.md"))

reusable-query.md should contain raw JavaScript that’s not wrapped in a code block.

2 Likes

Hi,

I’m the new guy around here, and I’ve got some tips and questions related to this topic. Which might be off target completely, but here goes.

First of all, using the Plaintext plugin, and adding js as an extension, one is able to edit javascript within Obsidian, albeit without some of the bells and whistles of a more dedicated code editor, like Visual Code 2. Only downfall so far, is that to create the file initially you either need to create an ordinary note within Obsidian, and rename it from .md to .js outside of Obsidian. Or you’ll create the file outside of Obsidian.

Secondly, I found a view such files with syntax highlighter, see my own answer in my own thread: Raw embed of javascript into a code block? - #3 by holroy :smiley:

Lastly, is there a particular reason you’re using dv.execute() instead of dv.query()? The latter seems to have an option to pass a file, pretending to be this, so that it can mimic being on the original note even more than what dv.execute() seems to do. It would also allow for even more post-processing, and handling after query execution if one would want that. See Dataview: Function to get length of unique values OR using nested queries - #2 by holroy, for an example where I post process a DQL query to show summary of the summaries.

Hi @holroy !

Welcome! Thanks for your note and your ideas. Your use of the plaintext, button, and templater plugins is very clever!

Yep. it’s because I want to embed the query results directly on the page. I don’t need to do any post-processing on the results.

1 Like

wow this is super cool. This trick can also be used to re-use a JavaScript file like below:

dv.executeJs(await dv.io.load("Scripts/dailyTaskDistribution/dailyTaskDistribution.js"))
1 Like

Wonderful work here. I stumbled across this completely accidentally today and it solved a problem I knew that I had before I began looking for a solution.

I’m developing a template that shows movies watched, books read each month. Across many years, there are many files I need to create. The problem with normal templating is should I make a change, I need to update many files.

This solves that perfectly, One .js file linked to all the others.

2 Likes

This is so useful. Thanks, @Craig.

  1. If I want multiple queries, is it best to put them in one js file or separate js files?

2. Does anyone know how to use this with the DQL query in a callout?

Two minutes after asking that question, the solution came to mind: put the DVJS in a callout in the placeholder. Doh!

> [!INFO] Quote  
> ```dataviewjs
>dv.view("/_inbox/t1");
>```

Hi @anon63144152, great question. I’m generally a fan of more atomic notes, so I would probably keep it to one file per query and then refer to them individually.

Of course, if the two queries depend on each other, or would always be together, then it might make sense to keep them in the same file.

1 Like

I think I am going to have to go for one query in each JS file as I can’t get two queries in the same file to run. I would ideally like to add some inline JS snippets in the JS file as well but not been able to make those work either. Baby steps. Lots of reading to do.

But brilliant idea. Loving the paths it is taking my mind along. :heart_eyes_cat::exploding_head::person_in_lotus_position:t3:

Inline JS snippets don’t work correctly in live preview from memory, have a look in reading mode - you might find they’re working there.

1 Like

Something like this works when placed directly in a MD note in both live preview and reading mode:

`$= moment(dv.current().file.day.toISODate()).diff(moment('2022-11-14'), 'years').toLocaleString('en-en') + " years"` / `$= moment(dv.current().file.day.toISODate()).diff(moment('2022-11-14'), 'days').toLocaleString('en-en') + " days"`   

But if I put it in its own JS file—exactly as it is written above—and then call it in a MD note it doesn’t work:

> [!INFO] Quote  
> ```dataviewjs
>dv.view("/js/t1");
>```

I am also trying to put two DQL tables in one JS file but can’t get that to work as yet.

dv.execute(`

TABLE
file.tags as Tags
WHERE file.cday = this.file.day
or file.mday = this.file.day
SORT file.mtime desc
LIMIT 10

`);

dv.execute(`

dataview
TABLE
file.tags as Tags
FROM #obsidian
SORT file.mtime desc
LIMIT 10

`);

Busy reading the effing manual :smiling_face_with_tear: