I think it is more vizualization issue rather than a bug. The quotation marks on the right panel is a denotion indicating that the expression resolves into a string and they are not a part of the string per se. It would be very frustrating if every expression resolved into a quoted string as this would disable embedding numbers, objects, arrays, numbers as is to expand the JSON structure.
So, when you want to embed a string as such you need to embrace it in double quote marks.
For example, "prop": {{ "abcd" }}
will resolve in "prop": abcd
. This is what you are doing here by "prop": {{ $json.content }}
(sorry for not quoting your actual content accurately, I was too lazy to retype from video). What you want instead is "prop": "{{ "abcd" }}"
to have expression output quoted.
But even more systematic approach (that would deal with escaping all quotation marks, backslashes etc) is to JSON.stringify
every string you may have as a result of expression evaluation. This would be {{ JSON.stringify($json.content) }}
in your scenario. The expression will result in a properly formatted string, embraced in double quotation marks, escaped double quotation marks and escape characters per se where required.
Here is a playground demonstrating the above. Notice what happens with stringified3v2
and compare with stingified3v1
with which it shares the same input from the previous node.
If the above helps you to understand mechanics behind JSON documents composition, please mark this post as a
Solution.
P.S. This peculiarity is not specific to n8n.
Here is some code in vanilla JS that replicates n8n behavior, to see how it works.
const objJson = JSON.stringify({
a: 5,
b: "B",
c: { p1: "P1", p2: [1, 2, 3] },
});
const jsonDoc = `{
"obj1": ${objJson},
"obj2": ${JSON.stringify(objJson)}
}`;
const parsedJson = JSON.parse(jsonDoc);
console.log("jsonDoc:");
console.dir(jsonDoc);
console.log("parsedJsonDoc:");
console.dir(parsedJson);
Copy-paste this to Chrome dev tools and execute to see the effect. You will see that obj1
resolves to a proper object (despite the input being stringified) while obj2
is still a JSON string.