I'm fetching data in React from a MySQL database. MySQL auto-escapes my values including nested objects. I'm using the .json()
function on the top-level but i'm not able to use this on sub-levels, nor JSON.parse(response[0].data)
will work.
What is the right way of doing this?
fetch(`http://localhost:3000/getQuiz${window.location.pathname}`, requestOptions)
.then(response => response.json())
.then(response => {
console.log(response)
// {
// "id": 1,
// "url": "asd2q13",
// "data": "{name: \"Marie\", answers:[\"1\", \"3\", \"0\"]}"
// }
console.log(typeof response)
// object
console.log(response[0].data)
// {name: "Marie", answers:["1", "3", "0"]}
console.log(typeof response[0].data)
// string
console.log(response[0].data.name)
// undefined
})
CodePudding user response:
The response.data
is not a valid JSON string. You can try:
const response = {
"id": 1,
"url": "asd2q13",
"data": "{name: \"Marie\", answers:[\"1\", \"3\", \"0\"]}"
}
console.log(eval('(' response.data ')'))
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Or Better:
const response = {
"id": 1,
"url": "asd2q13",
"data": "{name: \"Marie\", answers:[\"1\", \"3\", \"0\"]}"
}
function looseJsonParse(obj) {
return Function('"use strict";return (' obj ')')();
}
console.log(looseJsonParse(response.data))
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
But,
Warning: Executing JavaScript from a string is an enormous security risk. It is far too easy for a bad actor to run arbitrary code when you use
eval()
. See Never use eval()!, below.
I suggest you serialize the data
correctly on the backend. I think the MySQL database driver can do this. Also, see Parsing JSON (converting strings to JavaScript objects)
CodePudding user response:
MySQL (MySQL2) for Node was the big problem here. It's suppose to serialize "automatically", but somehow it ends up all wrong.
If I do JSON.Stringify()
explicitly for the nested part before storeing it in the database it works!
const sendToDatabase = () => {
let nested = JSON.stringify({ name: "Marie", answers: ["2", "1", "0"] })
let post = { url: "asd2q13", data: nested}
var query = connection.query(
"INSERT INTO users SET ? ", post,
function (error, results, fields) {
if (error) throw error;
}
);
console.log(query.sql);
};
Then I call this on the front end
console.log(JSON.parse(response[0].data).name)
// Marie (string)
console.log(JSON.parse(response[0].data).answers)
// ["2", "1", "0"] (array)
The raw output from this is
{"name":"Marie","answers":["2","1","0"]}
insted of
{name: \"Marie\", answers:[\"1\", \"3\", \"0\"]}