Accessing frontmatter list in JS-Engine

What I’m trying to do

So I’m trying to setup some automation for a dnd character sheet. The specific thing I’m working on now is calculating and modifications to my spell attack and dc based on attuned magic items.

I have a list in my frontmatter of attuned magic items, and a javascript block at the bottom of the page to calculate the modifications based off if certain items are in the attuned list. and then update those numbers in frontmatter.


Unfortunately, my codeblock isn’t recognizing that the attuned list exists, and thus can’t be parsed.

Things I have tried

I’ve done a fair amount of digging through the docs of both the Obsidian API and JS-Engine (the latter of which seems to be frustratingly limited btw, at least from what I could find), though I admit I’m not too familiar with the guts of the system.

I thought perhaps property lists weren’t technically arrays, so I did an isolation test in a separate block where I just tried to print the attuned list, but received the same error.

Any thoughts?

context.bound comes from Meta Bind’s JS View blocks. JS Engine doesn’t set it, so context.bound is undefined and reading .attuned from it throws. In a js-engine block, context holds file (the note’s TFile) and metadata (its metadata cache), so the list is at context.metadata.frontmatter.attuned.

The next line would fail too. processFrontMatter takes a TFile, not a path, and this in a JS Engine block is the plugin’s execution object, not your note. Pass context.file instead:

const fm = context.metadata?.frontmatter ?? {};
const attuned = fm.attuned ?? [];
let spat = 0;
let dc = 0;

if (attuned.includes("+1 Wand")) spat += 1;
if (attuned.includes("+1 All-Purpose Tool")) {
    spat += 1;
    dc += 1;
}

if (fm.wand_bonuses !== spat || fm.dc_bonuses !== dc) {
    await app.fileManager.processFrontMatter(context.file, (frontmatter) => {
        frontmatter.wand_bonuses = spat;
        frontmatter.dc_bonuses = dc;
    });
}

return 'running';

The block runs each time the note renders, and the if around processFrontMatter keeps it from rewriting the file when the numbers haven’t changed.

One more thing from your screenshot: attuned holds slot1, slot2, slot3 right now, so both checks come out false and you’ll get 0 until the item names go in that list.

I ran this block on Obsidian 1.13.7 with JS Engine 0.3.6: it wrote wand_bonuses: 2 and dc_bonuses: 1 once, and reopening the note or switching to reading view didn’t write again.