Reputation: 2950
So, I have an object whose properties also contain json strings within them. When serializing this object, this is the string I get:
[{
"template": 1,
"action_json": "{\"id\":\"1\",\"action\":\"An action for all of IT!\",\"date_agreed\":\"2018-08-10\",\"complete_by\":\"2018-08-31\",\"responsible_departments\":[\"8\"],\"responsible_employees\":[\"1629\",\"112\",\"1374\"],\"priority\":\"High\"}",
"template_json": "{\"columns\":[{\"id\":\"id\",\"title\":\"Task Number\",\"default\":true,\"type\":\"auto\"},{\"id\":\"action\",\"title\":\"Action Agreed\",\"default\":true,\"type\":\"longtext\"},{\"id\":\"date_agreed\",\"title\":\"Date Agreed\",\"default\":true,\"type\":\"date\"},{\"id\":\"complete_by\",\"title\":\"Complete By\",\"default\":true,\"type\":\"date\"},{\"id\":\"responsible_departments\",\"title\":\"Responsible Departments\",\"default\":true,\"type\":\"option\"},{\"id\":\"responsible_employees\",\"title\":\"Responsible Employees\",\"default\":true,\"type\":\"option\"},{\"id\":\"priority\",\"title\":\"Priority\",\"default\":true,\"type\":\"option\",\"options\":[\"High\",\"Medium\",\"Low\"]}]}"
}, {
"template": 1,
"action_json": "{\"id\":\"1\",\"action\":\"Action numero uno\",\"date_agreed\":\"2018-08-10\",\"complete_by\":\"2018-08-10\",\"responsible_departments\":[\"8\"],\"responsible_employees\":[\"112\"],\"priority\":\"High\"}",
"template_json": "{\"columns\":[{\"id\":\"id\",\"title\":\"Task Number\",\"default\":true,\"type\":\"auto\"},{\"id\":\"action\",\"title\":\"Action Agreed\",\"default\":true,\"type\":\"longtext\"},{\"id\":\"date_agreed\",\"title\":\"Date Agreed\",\"default\":true,\"type\":\"date\"},{\"id\":\"complete_by\",\"title\":\"Complete By\",\"default\":true,\"type\":\"date\"},{\"id\":\"responsible_departments\",\"title\":\"Responsible Departments\",\"default\":true,\"type\":\"option\"},{\"id\":\"responsible_employees\",\"title\":\"Responsible Employees\",\"default\":true,\"type\":\"option\"},{\"id\":\"priority\",\"title\":\"Priority\",\"default\":true,\"type\":\"option\",\"options\":[\"High\",\"Medium\",\"Low\"]}]}"
}]
Which is fine, this is valid JSON.
The problem arises when I try to create a JavaScript object by parsing this string (using PHP):
echo "<script>
var employeeActions = JSON.parse('".json_encode($employeeActions)."');
</script>";
And then I get:
JSON.parse Error: Invalid character at position:33
When inspecting the page once it's loaded, here is what is echoed through my PHP script:
<script>
var employeeActions = JSON.parse('[{"template":1,"action_json":"{\"id\":\"1\",\"action\":\"An action for all of IT!\",\"date_agreed\":\"2018-08-10\",\"complete_by\":\"2018-08-31\",\"responsible_departments\":[\"8\"],\"responsible_employees\":[\"1629\",\"112\",\"1374\"],\"priority\":\"High\"}","template_json":"{\"columns\":[{\"id\":\"id\",\"title\":\"Task Number\",\"default\":true,\"type\":\"auto\"},{\"id\":\"action\",\"title\":\"Action Agreed\",\"default\":true,\"type\":\"longtext\"},{\"id\":\"date_agreed\",\"title\":\"Date Agreed\",\"default\":true,\"type\":\"date\"},{\"id\":\"complete_by\",\"title\":\"Complete By\",\"default\":true,\"type\":\"date\"},{\"id\":\"responsible_departments\",\"title\":\"Responsible Departments\",\"default\":true,\"type\":\"option\"},{\"id\":\"responsible_employees\",\"title\":\"Responsible Employees\",\"default\":true,\"type\":\"option\"},{\"id\":\"priority\",\"title\":\"Priority\",\"default\":true,\"type\":\"option\",\"options\":[\"High\",\"Medium\",\"Low\"]}]}"},{"template":1,"action_json":"{\"id\":\"1\",\"action\":\"Action numero uno\",\"date_agreed\":\"2018-08-10\",\"complete_by\":\"2018-08-10\",\"responsible_departments\":[\"8\"],\"responsible_employees\":[\"112\"],\"priority\":\"High\"}","template_json":"{\"columns\":[{\"id\":\"id\",\"title\":\"Task Number\",\"default\":true,\"type\":\"auto\"},{\"id\":\"action\",\"title\":\"Action Agreed\",\"default\":true,\"type\":\"longtext\"},{\"id\":\"date_agreed\",\"title\":\"Date Agreed\",\"default\":true,\"type\":\"date\"},{\"id\":\"complete_by\",\"title\":\"Complete By\",\"default\":true,\"type\":\"date\"},{\"id\":\"responsible_departments\",\"title\":\"Responsible Departments\",\"default\":true,\"type\":\"option\"},{\"id\":\"responsible_employees\",\"title\":\"Responsible Employees\",\"default\":true,\"type\":\"option\"},{\"id\":\"priority\",\"title\":\"Priority\",\"default\":true,\"type\":\"option\",\"options\":[\"High\",\"Medium\",\"Low\"]}]}"}]');
</script>
Upvotes: 0
Views: 2084
Reputation: 944114
The text you output from json_encode
will be passed through the parser for JavaScript string literals before it gets passed through JSON.parse
.
Since JSON and JS string literals use the same escape characters, this will break it! You are mashing up '
characters and data to try to construct a JS string literal programmatically, but the data includes characters with special meaning in JS.
"{\"i
That shows character 33. The JS string literal \"
will be parsed putting an unescaped "
in the string.
Forget about using JSON.parse
. Forget about trying to pass JSON to the browser. Remember that JSON and JavaScript literal syntax are more or less the same thing:
<script>
var employeeActions = <?php echo json_encode($employeeActions); ?>;
</script>
Upvotes: 3