On This Page:
Quick Links:
- Examples: Explore examples of the JSON Utility in action.
- API Documentation: View the full API documentation for the JSON Utility.
- Release Notes: Detailed change log for the JSON Utility.
- License: The YUI Library is issued under a BSD license.
- Download: Download the JSON Utility as part of the full YUI Library at YUILibrary.com.
Upgrade Notes
As of version 2.8.0, browser nativeJSON.parse
and JSON.stringify
will be used if present. The native implementations are much faster and safer than any implementation done in JavaScript.In versions prior to 2.8, the signature and behavior of
YAHOO.lang.JSON.stringify
differed slightly from the reference implementation at JSON.org and the ECMAScript version 5 specification that grew from that. In order to leverage native methods as browsers adopt the ECMAScript 5 spec, the YUI implementation of stringify
had to change so the behavior would be consistent across browsers with and without native JSON support.Specifically, the
stringify
behavior that has changed from 2.7.0 to 2.8.0 is:- Cyclical object references are no longer replaced with
null
, but now throw an Error. It is therefore recommended to wrap bothparse
andstringify
calls intry/catch
blocks. - The third parameter no longer limits the depth of object serialization, but is now used to trigger formatted output.
- Objects with a
toJSON
method will be first transformed using this method. - Object keys are no longer sorted alphabetically. This is possible to do with a replacer function.
- Overriding
YAHOO.lang.JSON.dateToString
is no longer recommended because the default ISO 8601 serialization is defined in the spec. If Dates must be formatted differently, either preprocess the data or setuseNativeStringify
tofalse
after overridingdateToString
.
YAHOO.lang.JSON.parse
has not changed in a few versions and remains a safe approximation of the spec. If your application requires specific functionality from 2.7.0 or prior, you can continue to use prior versions. They should correctly parse and produce valid JSON.Getting Started
To use the JSON Utility, include the following source files in your web page with the script tag:
<script src="http://yui.yahooapis.com/2.8.2r1/build/yahoo/yahoo-min.js"></script> <script src="http://yui.yahooapis.com/2.8.2r1/build/json/json-min.js"></script>
<script src="http://yui.yahooapis.com/2.8.2r1/build/yahoo/yahoo-min.js"></script>
<script src="http://yui.yahooapis.com/2.8.2r1/build/json/json-min.js"></script>
YUI Dependency Configurator:
Instead of copying and pasting the filepaths above, try letting the YUI dependency Configurator determine the optimal file list for your desired components; the Configurator uses YUI Loader to write out the full HTML for including the precise files you need for your implementation.Note: If you wish to include this component via the YUI Loader, its module name is
json
. (Click here for the full list of module names for YUI Loader.) -debug
versions of YUI JavaScript files, please download the library distribution and host the files on your own server.YAHOO.lang.JSON
is a static class that does not require instantiation. Simply access the methods you need from YAHOO.lang.JSON
.Using YAHOO.lang.JSON
The JSON Utility extends YAHOO.lang
, providing two static methods used for transforming data to and from JSON string format. These methods are described in the following sections.Parsing JSON string data into JavaScript data
Pass a JSON string toYAHOO.lang.JSON.parse
to convert it into live data. Optionally provide a second argument to filter or format the parsed object data during deserialization.
var jsonString = '{"productId":1234,"price":24.5,"inStock":true,"bananas":null}'; // Parsing JSON strings can throw a SyntaxError exception, so we wrap the call // in a try catch block try { var prod = YAHOO.lang.JSON.parse(jsonString); // We can now interact with the data if (prod.price < 25) { prod.price += 10; // Price increase! } } catch (e) { alert("Invalid product data"); }
var jsonString = '{"productId":1234,"price":24.5,"inStock":true,"bananas":null}';
// Parsing JSON strings can throw a SyntaxError exception, so we wrap the call
// in a try catch block
try {
var prod = YAHOO.lang.JSON.parse(jsonString);
// We can now interact with the data
if (prod.price < 25) {
prod.price += 10; // Price increase!
}
}
catch (e) {
alert("Invalid product data");
}
var currencySymbol = "$" function myFilter(key,val) { // format price as a string if (key == "price") { var f_price = currencySymbol + val.toFixed(2); } // omit keys by returning undefined if (key == "bananas") { return undefined; } } var formattedProd = YAHOO.lang.JSON.parse(jsonString, myFilter); // key "bananas" is not present in the formattedProd object if (YAHOO.lang.isUndefined(formattedProd.bananas)) { alert("We have no bananas today"); } // and the price is the formatted string "$24.50" alert("Your price: " + formattedProd.price)
var currencySymbol = "$"
function myFilter(key,val) {
// format price as a string
if (key == "price") {
var f_price = currencySymbol + val.toFixed(2);
}
// omit keys by returning undefined
if (key == "bananas") {
return undefined;
}
}
var formattedProd = YAHOO.lang.JSON.parse(jsonString, myFilter);
// key "bananas" is not present in the formattedProd object
if (YAHOO.lang.isUndefined(formattedProd.bananas)) {
alert("We have no bananas today");
}
// and the price is the formatted string "$24.50"
alert("Your price: " + formattedProd.price)
A word of caution against using eval
JSON data format is a subset of JavaScript notation, meaning that it is possible to use JavaScript eval
to transform JSON data to live data. However, it is unsafe practice to assume that data reaching your code is safe. eval
is capable of executing JavaScript's full notation, including calling functions and accessing cookies with all the privileges of a
. To ensure that the data is safe in browsers that don't yet support native JSON functionality, YAHOO.lang.JSON.parse
inspects the incoming string for potentially malevolent content (using methods derived from Douglas Crockford's json2.js) before giving it the green light to parse.
// UNSAFE
var data = eval('(' + shouldBeJsonData + ')');
// Safe
var data = YAHOO.lang.JSON.parse(shouldBeJsonData);
// UNSAFE
var data = eval('(' + shouldBeJsonData + ')');
// Safe
var data = YAHOO.lang.JSON.parse(shouldBeJsonData);
Stringifying JavaScript data into a JSON string
To convert a JavaScript object (or any permissable value) to a JSON string, pass that object to YAHOO.lang.JSON.stringify
and capture the returned string.
var myData = {
puppies : [
{ name: "Ashley", age: 12 },
{ name: "Abby", age:9 }
]
};
var jsonStr = YAHOO.lang.JSON.stringify(myData);
// jsonStr now contains the string (without the leading comment slashes)
// {"puppies":[{"name":"Ashley","age":12},{"name":"Abby","age":9}]}
var myData = {
puppies : [
{ name: "Ashley", age: 12 },
{ name: "Abby", age:9 }
]
};
var jsonStr = YAHOO.lang.JSON.stringify(myData);
// jsonStr now contains the string (without the leading comment slashes)
// {"puppies":[{"name":"Ashley","age":12},{"name":"Abby","age":9}]}
Stringify's full signature is
YAHOO.lang.JSON.stringify = function (data, filter, indent) { ... };
YAHOO.lang.JSON.stringify = function (data, filter, indent) { ... };
The following sections will discuss the second and third arguments.
Filtering data before serialization
The optional second argument to stringify
accepts either an array of strings or a function. Array values become a whitelist of object properties that should be serialized. A function value is known as a "replacer", and will be called for each object property:value pair, allowing you to modify the values or object structure as the input object is stringified.
// a detailed object record set
var records = [
{id:1, name: "Bob", age: 47, favorite_color: "blue"},
{id:2, name: "Sally", age: 30, favorite_color: "mauve"},
{id:3, name: "Tommy", age: 13, favorite_color: "black"},
{id:4, name: "Chaz", age: 26, favorite_color: "plaid"}
];
// Use an array of acceptable object key names as a whitelist.
// To create a JSON string with only age and id
var jsonStr = YAHOO.lang.JSON.stringify(records,["id","age"]);
// jsonStr now contains the string
// [{"id":1,"age":47},{"id":2,"age":30},{"id":3,"age":13},{"id":4,"age":26}]
// OR use a replacer function to modify the object en route
function replacer(key, value) {
if (key === 'age') {
return value > 35 ? '36-' :
value > 25 ? '26-35' :
value > 15 ? '16-25' :
'under 16';
} else if (key === 'name') {
return value; // also accept the name property
} else {
return undefined; // This will filter any other keys
}
}
var jsonStr = YAHOO.lang.JSON.stringify(records, replacer);
// jsonStr now contains the string
// [{"name":"Bob","age":"36-"},{"name":"Sally","age":"26-35"},...
// a detailed object record set
var records = [
{id:1, name: "Bob", age: 47, favorite_color: "blue"},
{id:2, name: "Sally", age: 30, favorite_color: "mauve"},
{id:3, name: "Tommy", age: 13, favorite_color: "black"},
{id:4, name: "Chaz", age: 26, favorite_color: "plaid"}
];
// Use an array of acceptable object key names as a whitelist.
// To create a JSON string with only age and id
var jsonStr = YAHOO.lang.JSON.stringify(records,["id","age"]);
// jsonStr now contains the string
// [{"id":1,"age":47},{"id":2,"age":30},{"id":3,"age":13},{"id":4,"age":26}]
// OR use a replacer function to modify the object en route
function replacer(key, value) {
if (key === 'age') {
return value > 35 ? '36-' :
value > 25 ? '26-35' :
value > 15 ? '16-25' :
'under 16';
} else if (key === 'name') {
return value; // also accept the name property
} else {
return undefined; // This will filter any other keys
}
}
var jsonStr = YAHOO.lang.JSON.stringify(records, replacer);
// jsonStr now contains the string
// [{"name":"Bob","age":"36-"},{"name":"Sally","age":"26-35"},...
Using toJSON to customize object serialization
Another option for including a special serialization strategy for your objects and classes is to assign a toJSON
method. The return value of yourObject.toJSON()
will be used in place of the object itself, and before the replacer is executed on that value.
function Student(first, last, level, grades) {
this.firstName = first;
this.lastName = last;
this.gradeLevel = level;
this.grades = grades;
}
// Offer a different object structure for JSON serialization
Student.prototype.toJSON = function () {
var gpa = 0,
i = this.grades.length;
while (i--) {
gpa += this.grades[i];
}
return {
name: this.lastName + ', ' + this.firstName,
gpa: ((gpa / this.grades.length) / 25).toFixed(1)
};
};
var students = [];
students.push( new Student("John", "Schmidt", 1, [95,90,92,87,100,100]) );
students.push( new Student("Irene", "Gamel", 1, [72,70,88,76,100,95]) );
students.push( new Student("Francis", "Yeh", 1, [53,67,100,0,78,88]) );
var studentJSON = YAHOO.lang.JSON.stringify(students);
// studentsJSON now contains the string
// [{"name":"Schmidt, John","gpa":"3.8"},{"name":"Gamel, Irene","gpa":"3.3"},{"name":"Yeh, Francis","gpa":"2.6"}]
function Student(first, last, level, grades) {
this.firstName = first;
this.lastName = last;
this.gradeLevel = level;
this.grades = grades;
}
// Offer a different object structure for JSON serialization
Student.prototype.toJSON = function () {
var gpa = 0,
i = this.grades.length;
while (i--) {
gpa += this.grades[i];
}
return {
name: this.lastName + ', ' + this.firstName,
gpa: ((gpa / this.grades.length) / 25).toFixed(1)
};
};
var students = [];
students.push( new Student("John", "Schmidt", 1, [95,90,92,87,100,100]) );
students.push( new Student("Irene", "Gamel", 1, [72,70,88,76,100,95]) );
students.push( new Student("Francis", "Yeh", 1, [53,67,100,0,78,88]) );
var studentJSON = YAHOO.lang.JSON.stringify(students);
// studentsJSON now contains the string
// [{"name":"Schmidt, John","gpa":"3.8"},{"name":"Gamel, Irene","gpa":"3.3"},{"name":"Yeh, Francis","gpa":"2.6"}]
Some native objects include a toJSON
method. For the most part, they do what you'd expect. new Boolean(true) => true
, for example. One notable exception are Date
instances, which serialize into an ISO 8601 format that looks like "1987-12-25T21:04:32Z".
Formatting the JSON output
To have stringify output JSON that's more human readable, pass either a string or number as the third parameter. Numbers will be translated into that number of spaces. Including the third parameter will trigger the output to be formatted with carriage returns and indentation using the specified string.
var records = [
{id:1, name: "Bob", age: 47, favorite_color: "blue"},
{id:2, name: "Sally", age: 30, favorite_color: "mauve"},
{id:3, name: "Tommy", age: 13, favorite_color: "black"},
{id:4, name: "Chaz", age: 26, favorite_color: "plaid"}
];
var formattedJsonStr = YAHOO.lang.JSON.stringify(records,["name","age"],4);
/* formattedJsonStr now contains the string
[
{
"name": "Bob",
"age": 47
},
{
"name": "Sally",
"age": 30
},
{
"name": "Tommy",
"age": 13
},
{
"name": "Chaz",
"age": 26
}
]
*/
var records = [
{id:1, name: "Bob", age: 47, favorite_color: "blue"},
{id:2, name: "Sally", age: 30, favorite_color: "mauve"},
{id:3, name: "Tommy", age: 13, favorite_color: "black"},
{id:4, name: "Chaz", age: 26, favorite_color: "plaid"}
];
var formattedJsonStr = YAHOO.lang.JSON.stringify(records,["name","age"],4);
/* formattedJsonStr now contains the string
[
{
"name": "Bob",
"age": 47
},
{
"name": "Sally",
"age": 30
},
{
"name": "Tommy",
"age": 13
},
{
"name": "Chaz",
"age": 26
}
]
*/
Native implementations may differ slightly in their formatted output, but it should continue to be readable.
About the JSON format
JSON is a lightweight data format based on the object notation of the JavaScript language. It does not require JavaScript to read or write; it is easy to parse by any language and libraries and tools exist in many languages to handle JSON. You'll find several examples of support for JSON data in the YUI Library.
There is a wealth of good information about JSON and its distinction from XML as a data interchange format at Douglas Crockford's site, JSON.org.
JSON data is characterized as a collection of objects, arrays, booleans, strings, numbers, and null. The notation follows these guidelines:
- Objects begin and end with curly braces ({}).
- Object members consist of a string key and an associated value separated by a colon ( "key" : VALUE ).
- Objects may contain any number of members, separated by commas ({ "key1" : VALUE1, "key2" : VALUE2 }).
- Arrays begin and end with square braces and contain any number of values, separated by commas ([ VALUE1, VALUE2 ]).
- Values can be a string, a number, an object, an array, or the literals
true
,false
, andnull
. - Strings are surrounded by double quotes and can contain Unicode characters and common backslash escapes ("new\nline").
JSON.org has helpful format diagrams and specific information on allowable string characters.
Here is a simple example of a valid JSON string:
More Here
Courtesy:http://developer.yahoo.com/yui/json/