Open jackreid opened 2 years ago
Can you give us a sequential set of steps to repro with?
I provided the code and the sequential steps above already. Is there something specific you want in addition? Through further experimentation, I have tried to find the simplest code that reproduces it. That is here:
var books = dv.pages('"01 Media/01 Books"')
.where(p => p.title &&
p.status == 'read').sort(p => p.dateRead);
function authorsCount(bookSet) {
let authorsDict = {};
for (i=0; i < bookSet.length; i++) {
var authors = bookSet[i].authors;
for (j=0; j < authors.length; j++) {
var author = authors[j];
if (author in authorsDict) {
authorsDict[author]++;
} else{
authorsDict[author] = 1;
}
}
}
return authorsDict;
}
var authorsDictFull = authorsCount(books);
var testArray = ["a", "b", "c"];
var testArraydv = dv.array(testArray);
dv.list(testArraydv)
Evidently it is something about the authorsCount() function that causes it. Will continue to investigate what is wrong with it, but still not sure why it causes a persistent bug that effects all my other files. As you can see, it doesn't matter if I am actually trying to print the output of authorsCount(), only that it has been run.
I will note that printing using dv.paragraph rather than dv.list works fine here.
Ya I didn't expect it to be persistent. I doubt I have the chops to investigate it but I'll give it a try when I can.
Also attaching a screenshot of dv.paragraph(authorsDictFull)
so you can see that the function is returning the dictionary that I would expect it to.
Further experimentation has allowed me to find a more simple, standalone example that reproduces the bug without having to run a query.
var testDict = {a: 1,
b: 2,
c: 3}
var items = Object.keys(testDict).map(function(key) {
return [key, testDict[key]];
});
var itemsArray = [];
for (i=0; i < items.length; i++) {
var itemAuthor = items[i][0];
var itemCount = items[i][1];
itemsArray.push({author: itemAuthor,
count: itemCount})
}
dv.list(items)
Not that dv.list is being applied to items, not itemsArray.
dv.paragraph(items)
returns:
dv.paragraph(itemsArray)
returns:
This errors appears to be happening inside the minified code for one of the libraries, for some reason. Additionally, apparently the itemsAray
actually affects whether or not this crashes, which makes absolutely no sense to me. What appears to be happening is this code somehow corrupts the library code, breaking all DataviewJS views.
Well, this is tremendously annoying. The issue is your loop - it should be
for (var i=0; i < items.length; i++)
instead of
for (i=0; i < items.length; i++)
Doing i=0
is overriding an esoteric, minified i
variable inside some minified library code; this is because the global state is still implicitly available in the eval'd script (which I something I thought I fixed, though quite obviously not). Using var i
or let i
creates a local variable which avoids this problem, at least.
Not sure off the top of my head how to prevent this; probably going to require setting up shadowing of the window
and global
variables inside scripts to hide global state, which is going to break some scripts.
Oh, wow, it didn't cross my mind that i
could be in use elsewhere. Actually declaring it with var i
or let i
does indeed seem to work. Returning to the itemsArray
example, the following resolved the issue:
var itemsArray = [];
let i;
for (i=0; i < items.length; i++) {
var itemAuthor = items[i][0];
var itemCount = items[i][1];
itemsArray[i] = {author: itemAuthor,
count: itemCount}
}
As does:
var itemsArray = [];
for (let i=0; i < items.length; i++) {
var itemAuthor = items[i][0];
var itemCount = items[i][1];
itemsArray[i] = {author: itemAuthor,
count: itemCount}
}
I admit that javascript is not my primary programming language so perhaps my original code was poorly written independent of this particular bug and the new versions are better practices. If so, I'm not sure that you actually need to change the backend code to prevent the bug. It might just be a matter of making the solution to the error visible on search engines, which this thread is a step towards.
Thanks so much for figuring this out! Dataview is by far and away my favorite Obsidian plugin.
Yeah, a very valid workaround is to jkust make sure to use let
/var
/const
in your variable definitions - I'll see what I can do about improving the error UX.
So I stumbled across this thread when looking up the same error. (I ended up abandoning the first code that caused it to, as it was not fit for purpose) I had some code that worked until I added "i = 0" above and " i++" inside a "foreach" loop the shortest code I found to reproduce:
i = 0
for(let page of dv.pages.file.tasks){
i++;
}
What blacksmithgu was saying earlier that using i
like that conflicts with obsidian's internal code. Declare it with a let
.
What happened?
What happened?
When using dataviewjs, if I try and render a malformed dv.table on a particular markdown file, I will sometimes trigger a particular error. Once this error has been triggered, all my dataviewjs scripts across all my files in my vault will only return the same error, even though they normally work fine. Closing and reopening obsidian (or reloading without saving) turns the other scripts back to normal (until I try and render the malformed script).
Bug Description
Step 1) Switch to read mode on a file with some malformed dv.table. For example:
Where topItemsdv is some dv.array.
Step 2) Get the following error:
Step 3) Delete the error producing code (Bug occurs whether or not I do this). If I do so, the error on this particular page goes away, as expected.
Step 4) Close the error producing file.
Step 5) Open some other file in the same vault that has a normally functional dataviewjs script. For example:
Step 6) Switch to read mode and receive the following errror:
Expectations
That an dataviewjs rendering error in one file should not cause errors in other, independent queries in other files, particularly after the error producing code is deleted.
Workaround
Either close and reopen obsidian or reload without saving.
Synopsis
One error replicates itself across all files in the vault
Environment
Using Obsidian v0.15.9 on Ubuntu 22.04.1 LTS Using Dataview v.0.5.41
DQL
No response
JS
Dataview Version
0.5.41
Obsidian Version
0.15.9
OS
Linux