What I’m trying to do
I have a folder with a series of session notes. I want to be able to create a new session note in that folder from a Templater template, and have its serial number automatically calculated and added to the frontmatter variable ‘sessionNumber’. It seems simple, but I have spent more than a week trying in vain to do it. I am new to Dataview, Templater, and JavaScript, so this has not helped, and I have been learning and troubleshooting as fast as I can.
Things I have tried
I have written a script in CommonJS module specification that I call using
<% tp.user.getNewSessionNumber %>
from the session note template. Its purpose is to find the new session number by checking the largest existing value of the sessionNumber
key in the frontmatter of the existing notes in the folder, and adding 1. At the moment, I am attempting to use Dataview to do this.
My script is finally working (it can be called by the template and throws no errors when it has safeguards). A new note is created with much of the desired initial content, but I cannot get it to assign the right session number (I get the result undefined). What I am currently trying to run is as follows:
function getNewSessionNumber (tp) {
let thisPatientSessionFolderPath = tp.file.folder(true);
// Get an array of all the pages in the specified folder
let pages = app.plugins.plugins.dataview.api.pages(`"${thisPatientSessionFolderPath}"`);
console.log("pages array: " + pages);
// Create a new array to store the session numbers
let sessionNumberList = [];
// Loop through each page and check if it has a session type and a valid sessionNumber property
for (let i = 0; i < pages.length; i++) {
let page = pages[i];
console.log("pages("+ i + "): " + sessionNumberList);
sessionNumberList.push(page.frontmatter.sessionNumber);
}
console.log("sessionNumberList: " + sessionNumberList);
// Get the largest session number in the sessionNumberList array
let largestSessionNumber = 0;
for (let i = 0; i < sessionNumberList.length; i++) {
let sessionNumber = sessionNumberList[i];
console.log("sessionNumberList(" + i + "):" + sessionNumber)
if (sessionNumber > largestSessionNumber) {
largestSessionNumber = sessionNumber;
}
}
// If session number list is empty, give it one value equal to 0
if (sessionNumberList.length === 0) {
sessionNumberList = [0];
}
// Calculate the next session number by adding 1 to the largest session number
let newSessionNumber = largestSessionNumber + 1;
console.log('newSessionNumber: ' + newSessionNumber);
return newSessionNumber;
}
module.exports = getNewSessionNumber;
This is an expanded and simplified version of the script in order to troubleshoot it. It has the safeguards removed. The previous version which is more compact and completed, and to which I may return when I solve the issues replaces the for
loop with
//Compact alternative to for loop, with safeguards
let sessionNumberList = app.plugins.plugins.dataview.api
.pages(`"${thisPatientSessionFolderPath}"`)
.where(page => page.frontmatter && page.frontmatter.type === 'session' && Number.isInteger(page.frontmatter.sessionNumber))
.map(page => page.frontmatter.sessionNumber);
To find out where the problem lies, I created a test folder with only one session note whose content is simply
---
type: session
sessionNumber: 1
---
This means that I am sure that note in the folder has the required frontmatter.
When I try to create the new session note from the template, I get the following error in the Obsidian console:
Templater Error: Template parsing error, aborting.
Cannot read properties of undefined (reading 'sessionNumber')
log_error @ plugin:templater-obsidian:61
errorWrapper @ plugin:templater-obsidian:81
await in errorWrapper (async)
write_template_to_file @ plugin:templater-obsidian:3718
on_file_creation @ plugin:templater-obsidian:3819
I cannot understand this, as sessionNumber
is clearly defined with the value 1
.
What is essentially happening when I run the full script is that the script finds no session numbers to populate the sessionNumberList
array, which results in it being empty.
I am really stumped as to what is going on here. If anyone can see the problem, I would be grateful if you could let me know.