• louis vuitton outlet
  • nike air max
  • ray ban uk
  • oakley sunglasses outlet
  • cheap jordan shoes
  • toms outlet
  • Cheap Oakleys Sunglasses
  • fifa coins
  • ray ban
  • cheap uggs
  • ray ban uk
  • nike air max
  • ray ban outlet
  • burberry uk
  • fut coins
  • fut 14 coins
  • fut coins
  • Christian Louboutin Outlet
  • michael kors outlet
  • coach outlet
  • louis vuitton outlet
  • fifa coins
  • ray ban
  • Custom iphone cases
  • nike
  • monster beats
  • nike outlet
  • Christian Louboutin Outlet
  • burberry outlet
  • coach outlet
  • iphone cases
  • LV
  • new balance
  • What You Might Not Know About JSON.stringify()

    What You Might Not Know About JSON.stringify()

    On January 29, 2013, in JavaScript, by Jim Cowart

    Nearly any developer spending even a moderate amount of time in JavaScript has had to, at some point, utilize JSON.stringify (and it’s counterpart, JSON.parse). JSON – JavaScript Object Notation – has become the go-to data-interchange format for many developers – with multiple languages capable of serializing to JSON, not just JavaScript itself. If you’re up late some night, unable to sleep, check out the history of JSON (tl;dr – Douglas Crockford is the brain behind it).

    When writing in JavaScript, JSON.stringify is the way we take a value and serilalize it to a string value representing the object:

    JSON.stringify({
        name: "Jim Cowart",
        country: "Jimbabwe"
    });
    // produces: "{"name":"Jim Cowart","country":"Jimbabwe"}"
    
    JSON.stringify("Oh look, a string!");
    // produces ""Oh look, a string!""
    
    JSON.stringify([1,2,3,4,"open","the","door"]);
    // produces "[1,2,3,4,"open","the","door"]"
    

    I won’t belabor all of the rules of what gets serialized, you can read more about that here.  But it’s essential you know the following:

    • a value of undefined, a function or XML value are ommitted – except when….
    • If you have an array with undefined, a function or an XML value, it will be emitted as a null value

    Let’s see about that:

    JSON.stringify({
        doStuff: function() { },
        doThings: [ function() {}, undefined ]
    });
    // produces: "{"doThings":[null,null]}"
    

    “Great, Jim. I get it. It’s a data interchange format. Behavior isn’t serialized. Most of the libraries I use these days handle serializing for me under the hood. So why write a blog post on JSON.stringify?! SHEESH!”

    I know, right? Still – there are some nice tricks that can come in handy. Many of the larger applications I’ve worked on recently have had debug flags that can be flipped to enable various console logging from different components active on the page. While we obviously don’t want to sift through endless lines of console.log information all the time – when it becomes necessary, wouldn’t it be nice if it were a bit more readable?

    // what if this:
    '{"name":"Jim Cowart","location":{"city":{"name":"Chattanooga","population":167674},"state":{"name":"Tennessee","abbreviation":"TN","population":6403000}},"company":"appendTo"}'
    
    // could be formatted like this, automagically?
    "{
        "name": "Jim Cowart",
        "location": {
            "city": {
                "name": "Chattanooga",
                "population": 167674
            },
            "state": {
                "name": "Tennessee",
                "abbreviation": "TN",
                "population": 6403000
            }
        },
        "company": "appendTo"
    }"
    

    JSON.stringify actually takes 3 parameters (JSON.stringify(value [, replacer [, space]])), the 3rd of which – the “space” argument – allows you to specify either a string character to use for indentation, or a number. If you pass a number, that many spaces (up to 10) will be used for indentation:

    var person = {
        name: "Jim Cowart",
        location: {
            city: {
                name: "Chattanooga",
                population: 167674
            },
            state: {
                name: "Tennessee",
                abbreviation: "TN",
                population: 6403000
            }
        },
        company: "appendTo"
    };
    // If you think the world only looks right through 2-
    // spaced-indentation, then you'll appreciate this:
    JSON.stringify(person, null, 2);
    /* produces:
    "{
      "name": "Jim Cowart",
      "location": {
        "city": {
          "name": "Chattanooga",
          "population": 167674
        },
        "state": {
          "name": "Tennessee",
          "abbreviation": "TN",
          "population": 6403000
        }
      },
      "company": "appendTo"
    }"
    */
    // If you're with "Team Tabs™", then you can
    // kiss those space indentations goodbye by
    // passing \t as the last arg
    JSON.stringify(person, null, "\t");
    /* produces:
    "{
        "name": "Jim Cowart",
        "location": {
            "city": {
                "name": "Chattanooga",
                "population": 167674
            },
            "state": {
                "name": "Tennessee",
                "abbreviation": "TN",
                "population": 6403000
            }
        },
        "company": "appendTo"
    }"
    */
    

    So – what about the second argument, simply passed as “null” in the above example? That’s the “replacer” argument. It can be an array or a function. If you pass an array, it should contain the keys you want exported from the object:

    // assuming the person object is the object from above
    JSON.stringify(person, ["name", "company"], 4);
    /* produces:
    "{
        "name": "Jim Cowart",
        "company": "appendTo"
    }"
    */
    

    If you pass a function, it takes two arguments: the key and the value:

    //  a bit contrived, but it shows what's possible
    // FYI - the entire value being serialized is the first thing
    // passed to the replacerFn, followed by each key on the
    // object, hence the check to see if key is falsy
    var replacerFn = function(key, value) {
        if(!key || key === 'name' || key === 'company') {
            return value;
        }
        return; // returning undefined omits the key from being serialized
    }
    JSON.stringify(person, replacerFn, 4);
    /* produces:
    "{
        "name": "Jim Cowart",
        "company": "appendTo"
    }"
    */
    

    You can use the replacer function approach to blacklist member names (in contrast to how the replacer argument as an array whitelists member names). I’ve found this approach to be useful when I need quick and targeted logging of certain values from a DOM element, but I want to prevent a serialization exception due to attempting to serialize a circular reference (which would occur if I drank some antifreeze and attempted to do something ridiculous like JSON.stringify(document.body)). Feel free to browse this fiddle for a simple example of using a replacer function to blacklist based on member name(s).

    Of course, another option for customizing an object’s JSON serialization is to add a “toJSON” method to the object:

    var person = {
        name: "Jim Cowart",
        location: {
            city: {
                name: "Chattanooga",
                population: 167674
            },
            state: {
                name: "Tennessee",
                abbreviation: "TN",
                population: 6403000
            }
        },
        company: "appendTo",
        toJSON: function () {
            return {
                booyah : this.name + ' , employer: ' + this.company
            };
        }
    };
    
    // The value returned from toJSON above is what
    // will actually get stringified:
    JSON.stringify(person, null, 4);
    /* produces:
    "{
        "booyah": "Jim Cowart , employer: appendTo"
    }"
    */
    

    “Seriously, Jim, there are bigger fish to fry than to write pretty JSON to a console.” You don’t have to convince me, I’m with you 110%. But I will say this, nicely formatted JSON makes a serious difference when you are wire-tapping a message bus for debugging visibility into the messages being published, or logging websocket payloads. Being able to selectively serialize objects by whitelisting member names with a replacer array argument (or blacklisting with a replacer function) can be very handy on DOM events/elements – helping you track down issues, or simply give you better visibility into complex interactions, without de-railing you with serialization exceptions.

    Some further reading/exploring:
    You’ll notice I never EVER said “JSON object” when describing JSON, or objects. Ben Alman has a great post explaining why “There’s no Such Thing as a JSON Object“. The only thing he fails to mention is that saying “JSON Object” kills kittens and puppies. By the dozens. True Story.

    If you feel the need to write your own ‘circular reference safe’ JSON serializer in JavaScript, check out @getify’s idea here.

    Also – kudos to Elijah Manor and/or Doug Neiner. I’m fairly certain one of them was the first to mention to me that JSON.stringify can format output.

    So, go forth. Stringify.

    Tagged with:  
    • Daniel Thul

      Thanks! Realy useful!

    • JeremyRDeYoung

      love the fact you used the word automagically – great blog by the way!

    • http://kun.io/ William P. Riley-Land

      Nice overview!

    • Priamo74

      Very nice, man. Hope I’ll never forget about this lesson. Great job.

    • http://twitter.com/WhateverCode Whatever Code

      Great, nice tricks man!

    • Pingback: Things about JSON.stringify() I didn’t know « MikeScott8 Programming Thoughts

    • Pingback: Friday Links #240 | Blue Onion Software *

    • http://www.wpguru.com.au/ Wordpress Developer Sydney

      Hi Jim,
      Great tutorial. Really impressive.
      Are you on Google+.

      • http://ifandelse.com Jim Cowart

        Thanks! Yes, I am – though I admit I’m not on it as much as twitter: me at ifandelse dot com.

    • Ethan Zhang

      good to learn, thanks very much

    • Pingback: Rounded Corners 394 — Shake to shoot | Labnotes

    • Pingback: Web links 05/02/2013 — Nevma Developers Blog

    • http://blakesimpson.co.uk/ Blake Simpson

      Thanks for the post, I haven’t ever seen stringify using multiple arguments before.

    • David Swift

      Thanks, this helped me correct a bit of nastiness I caused by implementing domains in my node.js project.

    • MR NoJon

      Is it possible to build a json string i a loop? Someting like this?
      Im an early bird on json an pls xcuse my stupid question.

      var jsonData = “[";
      for (var i = 0; i < 1; i++) {
      var datefrom = new Date();
      var dateto = new Date();
      var name = "name" + i;

      jsonData += "{"name" : "" + i + "","desc" : "" + i + "","values:" : [{"id":"" + i + "","from":"/Date(1320301600000)/","to":"/Date(1320301600000)/","desc":"" + i + "","label":"" + name + "","customClass":"ganttRed"}]}"
      }
      jsonData += "]";

      • http://kun.io/ William P. Riley-Land

        Yes, it’s totally possible. But, there’s just about no reason to do that in production code. Also, this may be a matter of personal preference, but I consider it easier to read strings with a bunch of quotation marks when written like: ‘{“name”:”‘ + name + ‘”, “desc”:”‘ + desc + ‘”}” or “It’s a beautiful day” :)

        • MR NoJson

          But im still struggling with this:

          var jsonData = “[";
          for (var i = 0; i < 5; i++) {
          var datefrom = new Date();
          var dateto = new Date();
          var name = "name" + i;
          jsonData += '{"name":"' + i + '","desc" : "' + i + '","values:" : [{id":"' + i + '","from":"/Date(1320301600000)/","to:"/Date(1320301600000)/","desc":"' + i + '","label":"' + name + ",customClass:ganttRed}]}"
          }
          jsonData += "]";

          im trying to dynamicly build a json for this Project:

          http://taitems.github.io/jQuery.Gantt/

          But im so lost right now…

          • http://kun.io/ William P. Riley-Land

            var a = [];

            a.push({ name: ‘x1′ });

            a.push({ name: ‘x2′ });

            console.log(JSON.stringify(a));

    • http://twitter.com/yodirkx Rudie Dirkx

      Actually “Douglas Crockford is [not!] the brain behind it”. He’s just the one that ‘standardized’ it. He admittedly “took it from brighter minds” (parafrasing). Details.

    • Pingback: JSON.stringify()’s arguments | Bram.us

    • Robert Chesley

      Very helpful and thorough post. Many Thanks.

    • Design by Adrian

      Thanks for this! I found the 2nd parameter to be… magical!

    • Wagner

      Crockford is full of crock. Who names a function “stringify”, it;s not even a word! That’s one way to ‘messify’ a language. He should follow convention and have named it toString.

      • Axel

        No, JSON.toString(); would just convert the JSON object to a string…

    • bigFan

      Thanks for the great explanation!
      I was getting a cyclic error doing a set item to local storage on something saved from a previous session. But then I passed in the replacer array and space arguments and it all works perfectly now. Thanks!

    • srikanth

      Thank you so much you saved my time, you made my day