Is it possible to make a dataviewjs query that triggers when you press

Is it possible to make a dataviewjs query that will be triggered when a callout (or header) is clicked ? so that it is not loaded immediately with the note, but is executed only when needed.
If possible, please send me a sample javascript code at once.

I’ve come up with a simple solution that involves using an IntersectionObserver: Lazyload dataview/dvjs codeblock

It’s not perfect as I know it might not trigger in certain context (when viewed inside an embed or in a popover I believe). You can try efrec’s implementation if it happens. I’ll try to edit mine to make sure it covers most edge cases, but for now it works for what you’ve asked

1 Like

I tried to apply your code, I created lazyload.js in the Scripts folder where I have view.js and just copied your code for it, then I simplified your function a bit in view.js for the example

function f() {
    dv.span(“TEST \n”); 
}

and called it like this
await dv.view(“lazyload”, f);
I did all this in view.js.
And I just saw the TEST text right after loading the note into obsidin
What am I doing wrong and where is the mouse click processing to load the request ?

I also tried to test the dataviewjs query from obsidian itself ?

` ``dataviewjs

const dql = ‘LIST “”’
await dv.view(“Scripts/lazyload”, dql)

` ``

and I didn’t see anything.

As explained in the other post, the code block itself must be hidden for the lazy load script to work. What you’ll want to do is put your whole code block inside a closed (by default) callout that expand on click: Here is how you’d do it for example:

> [!NOTE]-
> ```dataviewjs
> await dv.view(`_js/lazyload`, () => {
> 	console.log(`I'm lazy loaded :D`)
> 	dv.span(`I'm lazy loaded :D`)
> })
> ```

Paste this into your file, open devtools and try for yourself, the console.log should occur just after you open the callout, not before.

Note that I’ve updated the original post so the script both handle dql and dvjs at the same time. Not sure why I didn’t write that to begin with, anyway it’s clearer now

1 Like

This code worked for me, I saw in the developer console the message I’m lazy loaded :smiley: after I clicked on callout

>[!NOTE]- 
>```dataviewjs 
>await dv.view(`Scripts/lazyload`, () => { 
>console.log(`I'm lazy loaded :D`) 
>dv.span(`I'm lazy loaded :D`)}) 
>```

Then I tried running my code from view.js, this is how it works for me

await dv.view(“Scripts”, {type: “sourse”, collout_view: “-”, note_name: “[]”});

but when I add it like this

> [!NOTE]- 
>```dataviewjs. 
>await dv.view(`Scripts/lazyload`, () => { 
>console.log(`I'm lazy loaded :D`) 
>await dv.view(“Scripts”, { type: “sourse”, collout_view: “-”, note_name: “[[]]”});})
>```

I get the error

Evaluation Error: SyntaxError: await is only valid in async functions and the top level bodies of modules
at DataviewInlineApi.eval (plugin:dataview:18869:21)
at evalInContext (plugin:dataview:18870:7)
at asyncEvalInContext (plugin:dataview:18877:16)
at DataviewJSRenderer.render (plugin:dataview:18906:19)
at DataviewJSRenderer.onload (plugin:dataview:18448:14)
at e.load (app://obsidian.md/app.js:1:1167250)
at DataviewApi.executeJs (plugin:dataview:19449:18)
at DataviewPlugin.dataviewjs (plugin:dataview:20357:18)
at eval (plugin:dataview:20243:124)
at app://obsidian.md/app.js:1:1222590.

I realize I’m doing something really stupid, but I can’t figure it out yet and make it work.

First, I have two comments:

  • Why is a there a . next to dataviewjs at the top?
  • Why are you using “curly” double quotes instead of the regular straight ones?

That aside, the reason you get this error message is that the callback arrow function that contains your second dv.view call isn’t async. I don’t know what your “Scripts” view does so maybe the following won’t do what you expect, but at least you should add the async keyword just before the () => {} part like so:

> [!NOTE]- 
>```dataviewjs
>await dv.view(`Scripts/lazyload`, async () => { 
>  console.log(`I'm lazy loaded :D`) 
>  await dv.view("Scripts", { type: "sourse", collout_view: "-", note_name: "[[]]"});
>})
>```
1 Like

It’s all working now, thank you!
I already made it work by poking and prodding by removing await before calling my function, but I think your variant where you need to add async is more correct and it will avoid bugs.

I don’t pay much attention to it, and why are curly double quotes bad ?

It’s a copying error actually I don’t have any point

One more question, is it possible to make the callout and the query that is triggered after the click are called not inside obsidian, but inside javascript

I tried that, but my sourses_from_all_children function is executed immediately on page load and under the callout I see undefined

dv.span(“> [!Related sourses]-\n ‘+await dv.view(Scripts/lazyload, async () => {+’>”+“+await sourses_from_all_children(”-“, ‘[]’)”;}));

As far as I know, only single quotes, double quotes and backticks are valid quotes in js. It’s useful to juggle between the three to rely on slash escapes as little as possible. I have no idea how you manage to make curly quotes work on your side.

Getting back to your question, I understand it but I’m having trouble following what you’ve written here… The syntax seems wrong to me. In general, insert as many new lines as necessary and indent your code. This will be a great help to anyone reading your code (including your future you).

I’ve come up with this and it works on my side

```dataviewjs
dv.span(`the callout below has been created with dataviewjs`)
dv.span(`> [!Related sourses]-
>~~~dataviewjs
>await dv.view('_js/lazyload', async () => {
>	console.log("I'm lazyloaded")
>})
>~~~
`);
```
1 Like

About the curly quotes, I figured it out, I don’t use them, the translator adds them, in the code I have regular straight quotes.

As for my question, I didn’t understand it right away, but it works!!!, I was confused by the ```dataviewjs at the beginning, I thought it should be run in obsidian. And I also didn’t realize that I had to use those ~~~ symbols.

PS I couldn’t make my code from the previous post more beautiful because it’s one line inside dv.span() where I form callout, call the function from lazyload.js and after it my own function, but besides it’s not pretty it’s also wrong

1 Like