Skip to content

dataviewjs: dv.executeJs causes double/multi rendering of html #2631

@VolatileDream

Description

@VolatileDream

What happened?

Loading and passing a template to dv.executeJs causes semi-random multi-rendering. It starts out rendering a single item, but then will randomly add duplicate html over time. I'm sure there's a pattern to the "random" i just don't know what it is. I have a theory that it might be related to the tryQuery calls embedded in the template?

Having seen that this problem has occurred previously (#1720, #1773, #1819, #2058) and how it was fixed (#1839) I went poking around. I suspect the issue is that the executeJs function adds the new child, and calls the load function on it in the wrong order (code)? I patched this locally and it seems to have fixed the issue: running addChild(...) first, then load.

edit: I tried to dig into this, but knowing very little about Obsidian plugins I didn't really get anywhere. The only conclusion I've come to is that my theory here is wrong. 😅


Given the following situation, i see the dv.table rendered multiple times. Leaving the file open, and taking notes in it will slowly cause more duplicates to get rendered into the document. Going to edit the dataview will remove all the duplicates when editing is done.

template.js:

// Given a daily file, find the previous and next files in the folder.
let current = dv.current();
let today = Date.parse(current.file.day);

let yesterday = (await dv.tryQuery(
`LIST FROM "${current.file.folder}"
WHERE date(file.name) < date("${current.file.name}")
SORT date(file.name) DESC
LIMIT 1`, current)).values;
let tomorrow = (await dv.tryQuery(
`LIST FROM "${current.file.folder}"
WHERE date(file.name) > date("${current.file.name}")
SORT date(file.name) ASC
LIMIT 1`, current)).values;

dv.table(["Previous", "Next",], [[yesterday[0], tomorrow[0]]]);

embedding this javascript snippet in other files:

// dataviewjs
let embed = await dv.io.load("template.js");
dv.executeJs(embed);

DQL

No response

JS

Edit after the fact: I've managed to reproduce this with this minimal JS:

let js = `
let p = await dv.tryQuery("TABLE FROM [[]]");
dv.paragraph(p);
`;
dv.executeJs(js);

Dataview Version

0.5.68

Obsidian Version

1.9.14

OS

MacOS & Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions