Here’s a PSA for all the heavy javascript users. This bug was pretty hard to debug since reading the template code didn’t show the problem.
Intro
For reasons, you want to store some data in JSON format in your note fields, which you will then parse with javascript in the card template and do stuff.
My_JSON_note_field:
{ "some_key": "some_value" }
Script:
// This will work, since the content was already a valid object literal
// But is of course dangerous, since your code will crash if there's a syntax error in the field content
var myData = {{My_JSON_note_field}}
So, you use some try / catch
and JSON.parse
to let the rest of your code run in the case of an error:
// Safe! maybe...
var myData;
try {
myData = JSON.parse("{{My_JSON_note_field}}");
} catch {
// handle error
}
The problem
The above is fine… as long as your JSON content is a single line! Consider this:
My_JSON_note_field:
{
"some_key": "some_value",
}
The reason you’d format the json with linebreaks would be to make making manual edits easier.
Script after replacement is done:
// Safe! maybe...
var myData;
try {
myData = JSON.parse("{
"some_key": "some_value", <--- Oops
}");
} catch {
// handle error
}
Because of the linebreaks, the string syntax is broken and the code will crash despite the try/catch.
The first code would’ve actually worked because the content is still a valid object literal…
// This will work, since the content was already a valid object literal
// But is of course dangerous, since your code will crash if there's a syntax error in the field content
var myData = {
"some_key": "some_value",
}
The solution: use `` instead of “”
Script:
// Crashproof!
var myData;
try {
myData = JSON.parse(`{{My_JSON_note_field}}`);
} catch {
// handle error
}
Script after replacement:
// Crashproof
var myData;
try {
myData = JSON.parse(`{
"some_key": "some_value",
}`);
} catch {
// handle error
}
Now the template literal will nicely handle any multi-line strings.
The next gotcha would of course be your content containing template literal variable syntax, but that will actually be caught in the try/catch.
My_JSON_note_field:
{
"some_key": "${why_would_you_do_this_though}",
}
Script after replacement:
// Crashproof!
var myData;
try {
myData = JSON.parse(`{
"some_key": "${why_would_you_do_this_though}",
}`);
} catch {
// A ReferenceError will be caught due to why_would_you_do_this_though not being defined
}