Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stringify objects through JSON's replacer function?

Here is my code:

BAD = {
          "a": "2",
          "b": 1,
          "c": "Nexus",
          "d": "Alligator",
          "e": 5,
          "f": 1431807036,
          "g": {
                    "2": {
                            "w": 17,
                            "b": 5
                         }
               }
      }

console.log(JSON.stringify(BAD, ['a', 'b', 'c', 'd', 'e', 'g']));

http://jsfiddle.net/whv7x6xc/1/

The keys a, b, c, d, e, and g are the only ones being stringified which is nice, but there is one problem. It's ignoring the object that is assigned to g.

enter image description here

But, if you do: console.log(JSON.stringify(BAD)); it shows the proper stringified version.

Edit: w and b are dynamic and changed periodically (come and go) though, so I cannot just hard-code them in.

like image 348
NiCk Newman Avatar asked May 16 '15 20:05

NiCk Newman


People also ask

How do I Stringify an array of objects in JSON?

Stringify a JavaScript ArrayUse the JavaScript function JSON. stringify() to convert it into a string. const myJSON = JSON. stringify(arr);

Does JSON Stringify work on objects?

JSON. stringify() will encode values that JSON supports. Objects with values that can be objects, arrays, strings, numbers and booleans. Anything else will be ignored or throw errors.

How do I Stringify an object in TypeScript?

stringify() method to convert an object to JSON in TypeScript, e.g. const json = JSON. stringify(obj) . The JSON. stringify method takes a value, converts it to a JSON string and returns the result.

How do you Stringify an object in Java?

We can convert Object to String in java using toString() method of Object class or String. valueOf(object) method. You can convert any object to String in java whether it is user-defined class, StringBuilder, StringBuffer or anything else.


1 Answers

JSON replacer is recursive. This then means it uses the same array for all objects it comes across. In other words, it uses the same values to map BAD.g's value. Since, Bad.g's value does not have any keys matching the ones you provided, nothing will get mapped properly. This means we have to add "2" to your array. Now "2" also has an object with different keys. We have already accounted for "b", so now we just need to add "w" to your array.

When providing an array to the replacer, best to think of the array as a list of all the keys you want mapped.

DEMO: http://jsfiddle.net/dirtyd77/whv7x6xc/4/

console.log(JSON.stringify(BAD, ['a', 'b', 'c', 'd', 'e', 'g', '2', 'w']));

Hope this helps and let me know if you have any questions.


Here is also a snippet from the documentation,

If you return any other object, the object is recursively stringified into the JSON string, calling the replacer function on each property, unless the object is a function, in which case nothing is added to the JSON string.


In the case for dynamic keys, you can always create a function to push to an array and use that array for your whitelist. Here is an example:

DEMO: http://jsfiddle.net/dirtyd77/whv7x6xc/5/

var BAD = {
    "a": "2",
    "b": 1,
    "c": "Nexus",
    "d": "Alligator",
    "e": 5,
    "f": 1431807036,
    "g": {
        "2": {
            "w": 17,
            "b": 5
        }
    }
}

var whitelist = [];

iterate(BAD);

console.log(whitelist, JSON.stringify(BAD, whitelist));

function iterate(obj){
    for(var key in obj){
        // may have to do some checking to ignore any keys you don't care about
        whitelist.push(key);
        // if value is an object, will use this same function to push to whitelist array
        if(typeof obj[key] === 'object'){
            return iterate(obj[key]);
        }
    }
}

You can also just use your existing whitelist and just append keys on your g key (given that isn't dynamic):

DEMO: http://jsfiddle.net/dirtyd77/whv7x6xc/6/

var whitelist = ['a', 'b', 'c', 'd', 'e', 'g'];

iterate(BAD.g);

console.log(whitelist, JSON.stringify(BAD, whitelist));

function iterate(obj){
    for(var key in obj){
        whitelist.push(key);
        if(typeof obj[key] === 'object'){
            return iterate(obj[key]);
        }
    }
}
like image 61
Dom Avatar answered Oct 25 '22 03:10

Dom