DEV Community

Cover image for Javascript: Convert nested JSON to simple JSON
Kurapati Mahesh
Kurapati Mahesh

Posted on • Updated on

Javascript: Convert nested JSON to simple JSON

This will be the very much used utility function we almost regularly use.

Depends on the data variety & structuring of data, API response can return much complex JSONs. Sometimes capturing just one field out of whole JSON won't be suffice. We might need to get many fields to show on web page. Traversing such complex JSON wouldn't be a good idea each time. If we can convert that in to simple JSON would be better based on the situation.

I hope this much introduction is enough. Let's jump into actual stuff.

Here, I am taking much nested JSON. I will convert that into to simple JSON.

So, here is my example JSON:

const obj = {
    first: {
        first: '1',
        second: {
            second: true,
            third: {
                third: 'third',
                fourth: {
                    fourth: 4
                }
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

My desired output would be:

{first: '1', second: true, third: 'third', fourth: 4}
Enter fullscreen mode Exit fullscreen mode

Take a look at input and output once again to get idea.

Let's code something to achieve above:

const simpleObj = {};
function destructure(obj) {
    for (let key in obj) {
        const value = obj[key];
        const type = typeof value;
        if (['string', 'boolean'].includes(type) || (type === 'number' && !isNaN(value))) {
            simpleObj[key] = value;
        } else if (type === 'object') {
            Object.assign(simpleObj, destructure(value));
        }
    }
    return simpleObj;
}

console.log(destructure(obj));
Enter fullscreen mode Exit fullscreen mode

for (let key in obj) { -> Which iterates over given object.

const value = obj[key];
const type = typeof value;
Enter fullscreen mode Exit fullscreen mode

capturing actual value and its type.

if (['string', 'boolean'].includes(type) || (type === 'number' && !isNaN(value))) {
            simpleObj[key] = obj[key];
Enter fullscreen mode Exit fullscreen mode

Validating if the value of key is not an object. Copying to sampleObj obj if it's not an object.

else if (typeof obj[key] === 'object') {
            Object.assign(simpleObj, destructure(obj[key]));
        }
Enter fullscreen mode Exit fullscreen mode

In case of object, calling the same function again (called recursion) to go to nested levels of the object. Also, assigning everything to sampleObj. Hence this single object would contain all the key value pairs at the end.

Lastly, returning that object and printing that to console.

I would appreciate suggestions, if we can achieve this in even more best way. Thanks.


💎 Love to see your response

  1. Like - You reached here means. I think, I deserve a like.
  2. Comment - We can learn together.
  3. Share - Makes others also find this resource useful.
  4. Subscribe / Follow - to stay up to date with my daily articles.
  5. Encourage me - You can buy me a Coffee

Let's discuss further.

  1. Just DM @urstrulyvishwak
  2. Or mention
    @urstrulyvishwak

For further updates:

Follow @urstrulyvishwak

Latest comments (12)

Collapse
 
ftonato profile image
Ademílson F. Tonato • Edited

Hello @urstrulyvishwak, thanks for sharing with us one of your real problems and also the solution you used.

The only time I needed something like this I used flattie, but it actually does a few different things than the solution you presented, and I understand that everything is born out of necessity.

Thinking about this very specific scenario that you brought us, I decided to create my own solution, and with it I added some things that your method doesn't handle and that can generate errors.

A simple example of a problem you might have is if you have a value that is of type Array, for example:

{
   one: {
     one: [1, 2, 3],
   },
}
Enter fullscreen mode Exit fullscreen mode

Therefore, my solution to the problem deals with the following data types:

  • String
  • Number
  • Boolean
  • Array
  • Date
  • Function
  • Map
  • Set
  • BigInt
  • Symbol
  • Buffer
  • Promise

I intend to expand even more as soon as I have some time 🚀

Here's the package: plain-object
11 kB (Minified) / 3.5 kB (Minified + Gzipped) and the repository.

Any suggestion is welcome o/

Thanks again for sharing with us

Collapse
 
urstrulyvishwak profile image
Kurapati Mahesh • Edited

Great Idea. Thank you so much. I covered the scenario to capture key values with value as primitive type.

Collapse
 
jeffwildesunrun profile image
jeff-wilde-sunrun
Collapse
 
tylim88 profile image
Acid Coder • Edited

I wrote a npm package that flatten the nested object, it also return accurate typing

npmjs.com/package/object-flat

flatten

Collapse
 
urstrulyvishwak profile image
Kurapati Mahesh

Thatz so cool. Superb.

Collapse
 
urstrulyvishwak profile image
Kurapati Mahesh

Good One. Great work.

Collapse
 
msabir profile image
imsabir

You can also use the spread operator for this:

Object.assign(
  {}, 
  ...function _flatten(o) { 
    return [].concat(...Object.keys(o)
      .map(k => 
        typeof o[k] === 'object' ?
          _flatten(o[k]) : 
          ({[k]: o[k]})
      )
    );
  }(obj)
)
Enter fullscreen mode Exit fullscreen mode

Explanation:
Recursively create an array of one-property objects, then combine them all with Object.assign.

This uses ES6 features including Object.assign or the spread operator, but it should be easy enough to rewrite not to require them.

*Spread Operator: *
The JavaScript spread operator ( ... ) allows us to quickly copy all or part of an existing array or object into another array or object.

For more: @msabir

Collapse
 
urstrulyvishwak profile image
Kurapati Mahesh

That so cool. Thanks. Helpful to many :)

Collapse
 
mattthecuber profile image
MattTheCuber

Also, this doesn't account for duplicate keys

Collapse
 
urstrulyvishwak profile image
Kurapati Mahesh • Edited

In general, in simple JSON duplicate keys are overridden by latest value. Please have a look at attached.

Collapse
 
mattthecuber profile image
MattTheCuber

If type is a number, doesn't that make isNaN() useless?

Collapse
 
urstrulyvishwak profile image
Kurapati Mahesh

NaN is also type of a number. Just avoiding it. That is upto our requirement wheather to include or exclude.

Thank you.