DB Folder formulas: how to count number of items in a relation field?

I would need a formula for DB Folder that counts how many items in total the following properties have: SUN, TUE, WED, THU. They are of the relation data type and typically they include 0-3 related items.

ChatGPT suggested the following:
${(row.SUN ? row.SUN.length : 0) + (row.TUE ? row.TUE.length : 0) + (row.WED ? row.WED.length : 0) + (row.THU ? row.THU.length : 0)}

This will display 0 when all fields are empty, and NaN when there’s content.

Is there a way to get the formula to count how many related items there are?

Further info: in my case these properties are inline fields, so I could try counting the values from the file itself, rather than the table.

I’m under the impression that dataview can detect inline fields and that it can be used in a DB Folder formula, but I don’t know how. ChatGPT:s solution doesn’t seem to take dataview into account so it seems overly complicated. It’s also saying that the values can’t be comma separated. Will I have to rewrite the fields using the unordered list syntax? I don’t want to start doing that unless it’s mandatory.

I tried making an inline field in one of the row files and using inline dataview code as the value. SUN, TUE, WED and THU are inline fields as well. This code correctly displays the number of values in the ‘SUN’ field:
= length(this.SUN)

But when I tried:
= length(this.SUN) + length(this.TUE)
…it doesn’t compute.

= length(this.TUE)
on its own sometimes computes and other times I get:

Dataview (for inline query ‘= length(this.TUE)’): No implementation of ‘length’ found for arguments: link

When DB Folder displays this cell, the result is always 0. I’m guessing that “this” can refer either to the row file or the DB Folder file, where the value is not set.

I found a solution to this on the plugin’s GitHub page, by AlfonsoRReyes.

It uses a separate javascript file named numElements.js, which is then referred to in the DB folder formula. The code inside the file is as follows:

function numElements(col) {
    dv = app.plugins.plugins.dataview.api;
    flattened = dv.array(col);
    // console.log(flattened)
    let i = 0
    flattened.forEach(elem => {
        i = i + 1;
    })
    return i;
}

module.exports = numElements;

The formula adapted to my use case:
${db.js.numElements(row.SUN) + db.js.numElements(row.TUE) + db.js.numElements(row.WED) + db.js.numElements(row.THU)}

The code must be saved in a folder inside the Obsidian vault and that folder must be linked to in DB folder settings. Obviously, javascript must be enabled.

I noticed one issue with the above code: it counts empty values as 1, rather than 0. Not sure if there would have been an easier solution, but I spent the evening with ChatGPT and after dozens of iterations, this is what works for me:

function numElements(col) {
    const dv = app.plugins.plugins.dataview.api;
    const flattened = dv.array(col);

    // Extract underlying array if it's a Proxy and log its content
    let underlyingArray;
    if (flattened.values) {
        underlyingArray = flattened.values;
    } else if (Array.isArray(flattened)) {
        underlyingArray = flattened;
    } else {
        return 0;
    }

    // Define a function to determine if a value is considered empty
    function isEmpty(value) {
        return value === undefined || value === null || (typeof value === 'string' && value.trim() === '') || value === "\\-";
    }

    // Check if the underlying array is empty or contains only empty values
    if (!underlyingArray || underlyingArray.length === 0 || underlyingArray.every(isEmpty)) {
        return 0;
    }

    let count = 0;
    underlyingArray.forEach(elem => {
        if (!isEmpty(elem)) {
            if (typeof elem === 'string') {
                // Check if the element contains '::' and non-whitespace characters after it
                const parts = elem.split('::');
                if (parts.length > 1 && parts[1].trim()) {
                    count += 1;
                }
            } else {
                // Non-string elements such as links should be counted
                count += 1;
            }
        }
    });

    return count;
}

module.exports = numElements;

For future reference, please do not ask the community to debug ChatGPT output. Thank you.

So noted. I considered just asking for help but then thought it would be generally better and more informative to share whatever attempts I’ve made so far.

Is it also discouraged to share AI-informed solutions like the one above?

Makes sense. It’s actually better to just ask for help, tho, because buggy AI code isn’t a useful starting point for anyone who can help. Just a brief “I asked ChatGPT but the results didn’t work” is good enough to show what you’ve tried.

We ask people not to answer others’ questions with AI solutions when they don’t know the answer themself or haven’t verified the output. Your case is different because it seems to work and you clearly stated that ChatGPT helped — plus of course it’s something you did for yourself to answer your own question.

Fair enough. Thanks for clarifying!

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.