简体   繁体   中英

JSON Parse nested objects in React

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
  })

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 + ')'))

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))

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)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM