Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to parse a partially stringified JSON received from an external API in Node.js?

I’m working with an external API in Node.js and receiving a JSON object that appears to be partially stringified. Here is a sample of what I’m getting:

{"2":["{\"1\":{\"3\":{\"1\":0,\"3\":{\"1\":[{\"1\":27,\"2\":{\"2\":\"Some data is not available\"}}]}},\"4\":\"3168034526981006837\"},\"2\":{\"1\":[{\"1\":\"Brand1\",\"2\":1,\"3\":[\"2400\",\"1900\",\"1900\",\"2900\",\"2400\",\"2900\",\"3600\",\"2900\",\"2900\",\"2900\",\"3600\",\"2900\"],\"6\":\"0\",\"200\":{\"1\":[\"2900\",\"0.0\",\"0.20833333333333334\",\"0.0\",\"316003\",\"616827\",\"0.0\"]}},{\"1\":\"Brand2\",\"2\":1,\"3\":[\"246000\",\"165000\",\"201000\",\"246000\",\"246000\",\"301000\",\"301000\",\"301000\",\"301000\",\"246000\",\"301000\",\"301000\"],\"6\":\"0\",\"200\":{\"1\":[\"246000\",\"0.22357723577235772\",\"0.22357723577235772\",\"0.0\",\"\",\"\",\"0.22357723577235772\"]}},{\"1\":\"Brand3\",\"2\":1,\"3\":[\"6600\",\"5400\",\"6600\",\"8100\",\"8100\",\"9900\",\"12100\",\"8100\",\"8100\",\"8100\",\"9900\",\"6600\"],\"6\":\"0\",\"200\":{\"1\":[\"8100\",\"-0.18518518518518517\",\"-0.18518518518518517\",\"0.0\",\"629943\",\"2000000\",\"-0.18518518518518517\"]}}],\"2\":{\"2\":[{\"3\":\"metric4\"},{\"3\":\"metric1\"},{\"3\":\"metric2\"},{\"3\":\"metric3\"},{\"3\":\"bid_min\"},{\"3\":\"metric5\"},{\"3\":\"metric6\"}]},\"3\":{\"1\":{\"1\":\"3\"}}}}","{\"1\":{\"3\":{\"1\":0,\"3\":{\"1\":[{\"1\":27,\"2\":{\"2\":\"Some data may be not available\"}}]}},\"4\":\"3168034526981006837\"},\"2\":{\"2\":[{\"1\":\"255000\",\"2\":{\"1\":2022,\"2\":5},\"3\":\"235938\"},{\"1\":\"172300\",\"2\":{\"1\":2022,\"2\":6},\"3\":\"159533\"},{\"1\":\"209500\",\"2\":{\"1\":2022,\"2\":7},\"3\":\"193668\"},{\"1\":\"257000\",\"2\":{\"1\":2022,\"2\":8},\"3\":\"236771\"},{\"1\":\"256500\",\"2\":{\"1\":2022,\"2\":9},\"3\":\"237411\"},{\"1\":\"313800\",\"2\":{\"1\":2022,\"2\":10},\"3\":\"291502\"},{\"1\":\"316700\",\"2\":{\"1\":2022,\"2\":11},\"3\":\"291567\"},{\"1\":\"312000\",\"2\":{\"1\":2022,\"2\":12},\"3\":\"289137\"},{\"1\":\"312000\",\"2\":{\"1\":2023,\"2\":1},\"3\":\"289713\"},{\"1\":\"257000\",\"2\":{\"1\":2023,\"2\":2},\"3\":\"237667\"},{\"1\":\"314500\",\"2\":{\"1\":2023,\"2\":3},\"3\":\"289775\"},{\"1\":\"310500\",\"2\":{\"1\":2023,\"2\":4},\"3\":\"287316\"}],\"6\":\"257000\"}}"]}

As seen above, \"1\":\"Brand2\" is a stringified JSON object inside the main JSON. I’m having trouble working with this data, as I need to access the values of nested fields.

I’ve tried using JSON.parse() to convert the stringified part to a JavaScript object, but it’s very inconvenient to write code like this const somewhatId= JSON.parse(data[2][0])['1'][0]['2']; it works, but the overall readibility of the code is awful.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

How can I properly parse this and work with it as a standard JSON object in Node.js?

>Solution :

You would write a function that recursively traverses the nested object, and when it identifies strings that could be parsed as JSON, it does so, returning the corresponding object. This object could then be fed again to the same function so that even deeper encoded JSON strings will be parsed.

This also means that string properties which can be interpreted as numbers (like "123.456") will be parsed into numbers (123.456). Same for "null", "false", "true"

Here is an implementation and how you can run it on your example:

function parseNestedJSON(obj) {
    if (typeof obj === "string") {
        try { // Parse this string as JSON if possible
            return parseNestedJSON(JSON.parse(obj));
        } catch {} // If not valid JSON, ignore error, and continue
    }
    if (Array.isArray(obj)) return obj.map(parseNestedJSON);
    if (Object(obj) !== obj) return obj; // Primitive
    return Object.fromEntries(Object.entries(obj).map(([k, v]) => 
        [k, parseNestedJSON(v)]
    ));
}

// Example input from the question
const response = {"2":["{\"1\":{\"3\":{\"1\":0,\"3\":{\"1\":[{\"1\":27,\"2\":{\"2\":\"Some data is not available\"}}]}},\"4\":\"3168034526981006837\"},\"2\":{\"1\":[{\"1\":\"Brand1\",\"2\":1,\"3\":[\"2400\",\"1900\",\"1900\",\"2900\",\"2400\",\"2900\",\"3600\",\"2900\",\"2900\",\"2900\",\"3600\",\"2900\"],\"6\":\"0\",\"200\":{\"1\":[\"2900\",\"0.0\",\"0.20833333333333334\",\"0.0\",\"316003\",\"616827\",\"0.0\"]}},{\"1\":\"Brand2\",\"2\":1,\"3\":[\"246000\",\"165000\",\"201000\",\"246000\",\"246000\",\"301000\",\"301000\",\"301000\",\"301000\",\"246000\",\"301000\",\"301000\"],\"6\":\"0\",\"200\":{\"1\":[\"246000\",\"0.22357723577235772\",\"0.22357723577235772\",\"0.0\",\"\",\"\",\"0.22357723577235772\"]}},{\"1\":\"Brand3\",\"2\":1,\"3\":[\"6600\",\"5400\",\"6600\",\"8100\",\"8100\",\"9900\",\"12100\",\"8100\",\"8100\",\"8100\",\"9900\",\"6600\"],\"6\":\"0\",\"200\":{\"1\":[\"8100\",\"-0.18518518518518517\",\"-0.18518518518518517\",\"0.0\",\"629943\",\"2000000\",\"-0.18518518518518517\"]}}],\"2\":{\"2\":[{\"3\":\"metric4\"},{\"3\":\"metric1\"},{\"3\":\"metric2\"},{\"3\":\"metric3\"},{\"3\":\"bid_min\"},{\"3\":\"metric5\"},{\"3\":\"metric6\"}]},\"3\":{\"1\":{\"1\":\"3\"}}}}","{\"1\":{\"3\":{\"1\":0,\"3\":{\"1\":[{\"1\":27,\"2\":{\"2\":\"Some data may be not available\"}}]}},\"4\":\"3168034526981006837\"},\"2\":{\"2\":[{\"1\":\"255000\",\"2\":{\"1\":2022,\"2\":5},\"3\":\"235938\"},{\"1\":\"172300\",\"2\":{\"1\":2022,\"2\":6},\"3\":\"159533\"},{\"1\":\"209500\",\"2\":{\"1\":2022,\"2\":7},\"3\":\"193668\"},{\"1\":\"257000\",\"2\":{\"1\":2022,\"2\":8},\"3\":\"236771\"},{\"1\":\"256500\",\"2\":{\"1\":2022,\"2\":9},\"3\":\"237411\"},{\"1\":\"313800\",\"2\":{\"1\":2022,\"2\":10},\"3\":\"291502\"},{\"1\":\"316700\",\"2\":{\"1\":2022,\"2\":11},\"3\":\"291567\"},{\"1\":\"312000\",\"2\":{\"1\":2022,\"2\":12},\"3\":\"289137\"},{\"1\":\"312000\",\"2\":{\"1\":2023,\"2\":1},\"3\":\"289713\"},{\"1\":\"257000\",\"2\":{\"1\":2023,\"2\":2},\"3\":\"237667\"},{\"1\":\"314500\",\"2\":{\"1\":2023,\"2\":3},\"3\":\"289775\"},{\"1\":\"310500\",\"2\":{\"1\":2023,\"2\":4},\"3\":\"287316\"}],\"6\":\"257000\"}}"]};
const result = parseNestedJSON(response);
console.log(result);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading