Converting an object to JSON and back again

JSON (JavaScript Object Notation) is very closely related to JavaScript objects because it's a subset of JavaScript. This task will demonstrate how to use the building blocks of JSON conversion: JSON.parse and JSON.stringify.

Getting ready

We'll need to create two new files called profiles.js and json_and_back.js.

How to do it...

Let's create the object that we'll later be converting to JSON.

module.exports = {
  ryan : {
           name: "Ryan Dahl",
           irc:'ryah',
           twitter:'ryah',
           github:'ry',
           location:'San Francisco, USA',
           description: "Creator of node.js"
          },
  isaac : {
            name: "Isaac Schlueter",
            irc:'isaacs',
            twitter:'izs',
            github:'isaacs',
            location:'San Francisco, USA',
            description: "Author of npm, core contributor"
           },
  bert : {
           name: "Bert Belder",
           irc:'piscisaureus',
           twitter:'piscisaureus',
           github:'piscisaureus',
           location:'Netherlands',
           description: "Windows support, overall contributor"
          },
  tj : {
          name: "TJ Holowaychuk",
          irc:'tjholowaychuk',
          twitter:'tjholowaychuk',
          github:'visionmedia',
          location:'Victoria, BC, Canada',
          description: "Author of express, jade and other popular modules"
          },
  felix : {
          name: "Felix Geisendorfer",
          irc:'felixge',
          twitter:'felixge',
          github:'felixge',
          location:'Berlin, Germany',
          description: "Author of formidable, active core developer"
          }
};

This object contains profile information on some of the leading members of the Node Community (though it's entirely non-exhaustive and doesn't even contain all of the core development team). One thing to note here is the use of module.exports. We'll be seeing more of this In Chapter 9, Writing Your Own Module. We're using module.exports to modularize our profiles object here in a bid to keep our code uncluttered. We can load any expression into module.exports, save it as a separate file (which in our case, we'll call profiles.js), and use require in our main file to dynamically load it at initialization.

var profiles = require('./profiles'), // note the .js suffix is optional

Nice and tidy. To convert our profiles object into a JSON representation, we use JSON.stringify, which will return a string composed of JSON data. We're going to fundamentally alter our object (which is now a string) using replace.

profiles = JSON.stringify(profiles).replace(/name/g, 'fullname'),

Here we have called replace, using a regular expression with the global g option to change every occurrence of name in our JSON string to fullname.

But wait! There appears to be some kind of mistake. Felix's last name is missing an umlaut! Let's correct it by converting our JSON data back into an object, and correct his name by altering the value of the re-designated fullname property:

profiles = JSON.parse(profiles);
profiles.felix.fullname = "Felix Geisendörfer";
console.log(profiles.felix);

When we run our application, console.log will output the following:

{ fullname: 'Felix Geisendörfer',
  irc: 'felixge',
  twitter: 'felixge',
  github: 'felixge',
  location: 'Berlin, Germany',
  description: 'Author of formidable, active core developer' }

The first key is now fullname, and Geisendörfer is spelled correctly.

How it works...

First, we have an everyday JavaScript object, which we serialize into a JSON representation. We also call the String.replace method on our JSON string, changing every occurrence of name into fullname.

Using replace in this way and context isn't an advisable practice since any occurrences of name are replaced. There could very easily have been other places in the string where name may have existed, which would be replaced unintentionally. We used replace here to affirm that profiles have become a JSON string, as we couldn't use replace on an object.

Then we convert our modified JSON string back into an object, using JSON.parse. To test that our keys were indeed transformed from name to fullname, and to affirm that we are again working with an object, we correct the felix profile via profiles.felix.fullname, and then log profiles.felix to the console.

There's more...

JSON is a highly versatile and flexible tool for cross-platform communication. Let's look at a more advanced application of the standard.

Constructing JSONP responses

JSONP (JSON with Padding) is a cross-domain policy workaround that allows developers to interface with resources on other domains. It involves defining a callback function on the client side that handles JSON via its first parameter, then passing the name of this callback as a query argument in the src attribute of a script element, which points to a web service on another domain. The web service then returns the JSON data, wrapped in a function named according to the query argument set client side. It's possibly easier to illustrate this in code.

<html>
<head>
<script>
  var who = 'ryan';
  function cb(o) {
    alert(o.name + ' : ' + o.description);
  }
  var s = document.createElement('script'),
  s.src = 'http://localhost:8080/?callback=cb&who=' + who;
  document.getElementsByTagName("head")[0].appendChild(s);
</script>
</head>
</html>

We define a function called cb which takes an object as its parameter, then we output the name and description properties. Prior to this, we set a variable called who which will be passed to the server to grab specific data for us. We then dynamically inject a new script element, setting src to a figurative third-party domain (which for easy demonstration is localhost) and adding callback and who query arguments. The value of callback matches the name of our function cb function. Our server uses this parameter to wrap JSON in a function invocation.

var http = require('http'),
var url = require('url'),
var profiles = require('./profiles'),

http.createServer(function (request, response) {
  var urlObj = url.parse(request.url, true), 
    cb = urlObj.query.callback, who = urlObj.query.who,
    profile;

  if (cb && who) {
    profile = cb + "(" + JSON.stringify(profiles[who]) + ")";
    response.end(profile);
  }

}).listen(8080);

We create a server, extract the callback and who query parameters, and write a response containing a function call passing our JSON data in as its parameter. This script is loaded by our client, where the cb function is called and JSON is received into the function as an object (because it looks like one).

Security and JSONP

Since JSONP uses script injection, any script could be inserted into our page. Therefore, it's highly recommended that this method only be used with trusted sources. An untrusted source could run evil code on the page.

See also

  • Browser-server transmission via AJAX discussed in this chapter
  • Working with real data: fetching trending tweets discussed in this chapter
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.46.36