YUI Library Home

Site Search (YDN & YUIBlog):

# YUI Library Examples: JSON Utility: Adding new object members during parsing

# JSON Utility: Adding new object members during parsing

This example shows how to use the `reviver` parameter in `JSON.parse` to add new object members and format existing members during the parsing phase.

View example in new window.

Choose a currency, then get the data

Inventory
SKU | Item | Price (USD) | Price (USD)
--- | --- | --- | ---
Click Get Data

### The data

The data returned from the server will be a JSON string containing this object structure:

[ {"SKU":"23-23874", "Price":23.99, "Item":"Helmet"}, {"SKU":"48-38835", "Price":14.97, "Item":"Football"}, {"SKU":"84-84848", "Price":3.49, "Item":"Goggles"}, {"SKU":"84-84843", "Price":183, "Item":"Badminton Set"}, {"SKU":"84-39321", "Price":6.79, "Item":"Tennis Balls"}, {"SKU":"39-48949", "Price":618, "Item":"Snowboard"}, {"SKU":"99-28128", "Price":78.99, "Item":"Cleats"}, {"SKU":"83-48281", "Price":4.69, "Item":"Volleyball"}, {"SKU":"89-32811", "Price":0.59, "Item":"Sweatband"}, {"SKU":"28-22847", "Price":779.98, "Item":"Golf Set"}, {"SKU":"38-38281", "Price":8.25, "Item":"Basketball Shorts"}, {"SKU":"82-38333", "Price":1.39, "Item":"Lip balm"}, {"SKU":"21-38485", "Price":0.07, "Item":"Ping Pong ball"}, {"SKU":"83-38285", "Price":3.99, "Item":"Hockey Puck"} ]

### Create a reviver function

We'll contain all the moving parts in the `YAHOO.demo.JSONReviver` namespace. In it, we'll include the currency exchange rates and a function to reference the rates to add a new member to the JSON response as it is being parsed.

YAHOO.util.Event.onDOMReady(function () { // Set up some shortcuts var JSON = YAHOO.lang.JSON, Dom = YAHOO.util.Dom, Event = YAHOO.util.Event, Demo; Demo = YAHOO.namespace('demo').JSONReviver = { rates : {"USD":1,"EUR":0.6661,...,"COP":2000 ,"ARS":3.1289}, currency : 'USD', // updated by the select element convert : function (k,v) { // 'this' will refer to the object containing the key:value pair, // so this will add a new object member while leaving the original // in tact (but formatted to two decimal places). If the original // is not needed, just return the converted value. if (k === 'Price') { var x = Math.round(v * Demo.rates[Demo.currency] * 100) / 100; this.convertedPrice = Demo.formatCurrency(x); // added to item return Demo.formatCurrency(v); // assigned to item.Price } return v; }, ... }; ...

### Sending the request and parsing the JSON response

When the Get Data button is clicked, we send an `asyncRequest` for the JSON data from YUI's Connection Manager. In our success handler, we pass our conversion function to `JSON.parse` with the response text. The resulting inventory records will have an additional member, `convertedPrice`. This data is then passed to a UI method to update the inventory table.

Event.on('demo_go','click',function (e) { var self = this, // Cache this for the async callback closure sel = Dom.get('currencies'); // Disable the button temporarily this.disabled = true; // Store the requested currency Demo.currency = sel.value; // Send the request for the JSON data YAHOO.util.Connect.asyncRequest('GET','assets/data.php',{ timeout : 3000, success : function (res) { var inventory; try { inventory = JSON.parse(res.responseText, Demo.convert); Demo.updateTable(inventory); } catch(e) { alert("Error getting inventory data"); } finally { self.disabled = false; } }, failure : function () { alert("Error getting inventory data"); } }); }); });

### Example markup

<div id="demo"> <p>Choose a currency, then get the data</p> <select id="currencies"> <option value="ARS">Argentine Peso</option> <option value="AUD">Australian Dollar</option> ... <option value="TWD">Taiwan Dollar</option> <option value="THB">Thai Baht</option> </select> <input type="button" id="demo_go" value="Get Data"> <table cellspacing="0"> <caption>Inventory</caption> <thead> <tr> <th>SKU</th> <th>Item</th> <th>Price (USD)</th> <th>Price (<span>USD</span>)</th> </tr> </thead> <tbody> <tr><td colspan="4">Click <em>Get Data</em></td></tr> </tbody> </table> </div>

### Full Code Listing

Below is the full source for the example, including the functions responsible for formatting the price and updating the UI.

YAHOO.util.Event.onDOMReady(function () { // Set up some shortcuts var JSON = YAHOO.lang.JSON, Dom = YAHOO.util.Dom, Event = YAHOO.util.Event, Demo; // To avoid a Safari issue with JSON reviver adding properties JSON.useNativeParse = false; Demo = YAHOO.namespace('demo').JSONReviver = { rates : {"USD":1,"EUR":0.6661,"GBP":0.5207,"AUD":1.1225,"BRL":1.609,"NZD":1.4198,"CAD":1.0667,"CHF":1.0792,"CNY":6.8587 ,"DKK":4.9702,"HKD":7.8064,"INR":42.0168,"JPY":109.8901,"KRW":1000,"LKR":107.5269,"MXN":10.1317,"MYR" :3.3167,"NOK":5.3277,"SEK":6.2617,"SGD":1.4073,"THB":33.7838,"TWD":31.1526,"VEF":2.1445,"ZAR":7.6923 ,"BGN":1.3028,"CZK":16.0514,"EEK":10.4275,"HUF":158.7302,"LTL":2.2999,"LVL":0.4692,"PLN":2.1758,"RON" :2.3804,"SKK":20.2429,"ISK":4.8008,"HRK":81.3008,"RUB":24.3309,"TRY":1.1811,"PHP":44.2478,"COP":2000 ,"ARS":3.1289}, currency : 'USD', formatCurrency : function (amt) { amt += amt % 1 ? "0" : ".00"; return amt.substr(0,amt.indexOf('.')+3); }, convert : function (k,v) { // 'this' will refer to the object containing the key:value pair, // so this will add a new object member while leaving the original // in tact (but formatted to two decimal places). If the original // is not needed, just return the converted value. if (k === 'Price') { var x = Math.round(v * Demo.rates[Demo.currency] * 100) / 100; this.convertedPrice = Demo.formatCurrency(x); // added to item return Demo.formatCurrency(v); // assigned to item.Price } return v; }, updateTable : function (inventory) { var demo = Dom.get('demo'), tbl = demo.getElementsByTagName('table')[0], tbody = tbl.getElementsByTagName('tbody')[0], col_header = tbl.getElementsByTagName('span')[0], tmp = document.createElement('div'), html = ["<table><tbody>"],i,j = 1,l,item; // Update the column header col_header.innerHTML = Demo.currency; if (inventory) { for (i = 0, l = inventory.length; i < l; ++i) { item = inventory[i]; html[j++] = '<tr><td>'; html[j++] = item.SKU; html[j++] = '</td><td>'; html[j++] = item.Item; html[j++] = '</td><td>'; html[j++] = item.Price; html[j++] = '</td><td>'; html[j++] = item.convertedPrice; html[j++] = '</td></tr>'; } } else { html[j++] = '<tr><td colspan="4">No Inventory data</td></tr>'; } html[j] = "</tbody></table>"; tmp.innerHTML = html.join(''); tbl.replaceChild(tmp.getElementsByTagName('tbody')[0], tbody); } }; Event.on('demo_go','click', function (e) { var self = this, // Cache this for the async callback closure sel = Dom.get('currencies'); // Store the requested currency // Disable the button temporarily this.disabled = true; // Store the requested currency Demo.currency = sel.value; YAHOO.util.Connect.asyncRequest('GET','assets/data.php',{ timeout : 3000, success : function (res) { var inventory; try { inventory = JSON.parse(res.responseText,Demo.convert); Demo.updateTable(inventory); } catch(e) { alert("Error getting inventory data"); } finally { self.disabled = false; } }, failure : function () { alert("Error getting inventory data"); } }); }); });

## Configuration for This Example

You can load the necessary JavaScript and CSS for this example from Yahoo's servers. Click here to load the YUI Dependency Configurator with all of this example's dependencies preconfigured.

### YUI Logger Output:

Note: You are viewing this example in debug mode with logging enabled. This can significantly slow performance.

Reload with logging
and debugging disabled.

### JSON Utility Examples:

- JSON with Connection Manager
- Rebuilding class instances from JSON data
- Adding new object members during parsing

### More JSON Utility Resources:

- User's Guide (external)
- API Documentation
- Cheat Sheet PDF (external)

Copyright © 2009 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings