Handling possible missing elements in a JSON file using templater

Hi guys,

I’ve tried to look at a bunch of different topics on templater to piece together a solution but I’m getting stuck trying handle missing values in a JSON file when running a templater script.

What I’m trying to do

Basically, I have created a JSON file with a bunch of data that changes depending on my day and I want to write this data to yesterday’s daily note’s frontmatter when I create today’s daily note. I managed to get that working but whenever there is a day when some fields don’t pull through into the JSON file, then the script bombs out.

Things I have tried

Full disclosure that I definitely at a beginner level with javascript, although I do have some other programming experience but I just don’t understand how null values are being handled.

I tried using the nullish assignment so something like:

const HR = data.find(item => item.name = "heart_rate").data[0].qty ??= -1;

But this doesn’t seem to accurately work. I have also tried splitting it out after the find function like:

const HR = data.find(item => item.name = "heart_rate") ??= -1;
if(!(HR === -1)){
HR = HR.data[0].qty;
}

and finally something like:

data.find(item => item.name = "heart_rate") ??= -1;
if(!(data.find(item => item.name = "heart_rate") === -1)){
HR = data.find(item => item.name = "heart_rate").data[0].qty;
}
else{
HR = -1
}

but none of these work. I keep getting the following error:
“Template syntax error: Invalid left-hand in assignment”

I have no errors if all the data is there which is why I assume the error arises from the missing data handling rather than any other part of the code. I have included the way I write the data to the old notes front matter if anyone wants to see if the error appears there.

tp.hooks.on_all_templates_executed(async () => {
	const file = tp.file.find_tfile(tp.file.path(true));
	await app.fileManager.processFrontMatter(prevFile, (frontmatter) => {
		frontmatter["steps"] = steps.toFixed(0);
		frontmatter["calories burnt"] = calories_burnt.toFixed(0);
		frontmatter["heart rate"] = heart_rate.toFixed(2);
		frontmatter["sleep hours"] = sleep_hours;
		frontmatter["in bed"] = in_bed;
		frontmatter["date"] = currDate;
		delete frontmatter["ignored"];
	});
});

I feel like there has got to be a simpler way to do all of this without so many different workarounds, but since I am still newish to javascript, I really can’t think of a better way

Should you use let instead of a const since you’re changing the value later?

(Note: I’m new to JavaScript too. I know just enough to be dangerous)

Hey, yeah I should have been using let but it was not the main issue here. After a good night sleep and some help from LLMs I did manage to solve it. The issue was that you can’t use the nullish operator when accessing pieces of an index if earlier pieces may not exist (I think). I rewrote the below line:

const HR = data.find(item => item.name = "heart_rate").data[0].qty ??= -1;

To become a two step process like:

const hr = parseData.data.metrics.find(item => item.name === "heart_rate");
const heart_rate = hr && hr.data && hr.data[0] ? hr.data[0].qty : -1;

So basically attempting to access the general location in the JSON file. Then checking if this or any subsequent path is undefined, and if it is, replacing it with negative 1.

It is definitely a case of knowing just enough javascript to be dangerous :slight_smile:

Thanks for trying to help.

1 Like

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