Home > other >  JSON Parse nested objects in React
JSON Parse nested objects in React

Time:11-11

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\"]}
  • Related