YUI Library Home

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.

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:

1
2    {"SKU":"23-23874""Price":23.99,  "Item":"Helmet"}, 
3    {"SKU":"48-38835""Price":14.97,  "Item":"Football"}, 
4    {"SKU":"84-84848""Price":3.49,   "Item":"Goggles"}, 
5    {"SKU":"84-84843""Price":183,    "Item":"Badminton Set"}, 
6    {"SKU":"84-39321""Price":6.79,   "Item":"Tennis Balls"}, 
7    {"SKU":"39-48949""Price":618,    "Item":"Snowboard"}, 
8    {"SKU":"99-28128""Price":78.99,  "Item":"Cleats"}, 
9    {"SKU":"83-48281""Price":4.69,   "Item":"Volleyball"}, 
10    {"SKU":"89-32811""Price":0.59,   "Item":"Sweatband"}, 
11    {"SKU":"28-22847""Price":779.98, "Item":"Golf Set"}, 
12    {"SKU":"38-38281""Price":8.25,   "Item":"Basketball Shorts"}, 
13    {"SKU":"82-38333""Price":1.39,   "Item":"Lip balm"}, 
14    {"SKU":"21-38485""Price":0.07,   "Item":"Ping Pong ball"}, 
15    {"SKU":"83-38285""Price":3.99,   "Item":"Hockey Puck"
16
view plain | print | ?

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.

1YAHOO.util.Event.onDOMReady(function () { 
2 
3// Set up some shortcuts 
4var JSON  = YAHOO.lang.JSON, 
5    Dom   = YAHOO.util.Dom, 
6    Event = YAHOO.util.Event, 
7    Demo; 
8 
9Demo = YAHOO.namespace('demo').JSONReviver = { 
10 
11    rates : {"USD":1,"EUR":0.6661,...,"COP":2000 ,"ARS":3.1289}, 
12 
13    currency : 'USD'// updated by the select element 
14 
15    convert : function (k,v) { 
16        // 'this' will refer to the object containing the key:value pair, 
17        // so this will add a new object member while leaving the original 
18        // in tact (but formatted to two decimal places).  If the original 
19        // is not needed, just return the converted value. 
20        if (k === 'Price') { 
21            var x = Math.round(v * Demo.rates[Demo.currency] * 100) / 100; 
22 
23            this.convertedPrice = Demo.formatCurrency(x); // added to item 
24 
25            return Demo.formatCurrency(v); // assigned to item.Price 
26        } 
27        return v; 
28    }, 
29    ... 
30}; 
31 
32... 
view plain | print | ?

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.

1Event.on('demo_go','click',function (e) { 
2 
3    var self = this,     // Cache this for the async callback closure 
4        sel  = Dom.get('currencies'); 
5 
6    // Disable the button temporarily 
7    this.disabled = true
8  
9    // Store the requested currency 
10    Demo.currency = sel.value; 
11 
12    // Send the request for the JSON data 
13    YAHOO.util.Connect.asyncRequest('GET','assets/data.php',{ 
14        timeout : 3000, 
15        success : function (res) { 
16            var inventory; 
17            try { 
18                inventory = JSON.parse(res.responseText, Demo.convert); 
19 
20                Demo.updateTable(inventory); 
21            } 
22            catch(e) { 
23                alert("Error getting inventory data"); 
24            } 
25            finally { 
26                self.disabled = false
27            } 
28        }, 
29        failure : function () { 
30            alert("Error getting inventory data"); 
31        } 
32    }); 
33}); 
34 
35}); 
view plain | print | ?

Example markup

1<div id="demo"
2    <p>Choose a currency, then get the data</p> 
3    <select id="currencies"
4        <option value="ARS">Argentine Peso</option> 
5        <option value="AUD">Australian Dollar</option> 
6        ... 
7        <option value="TWD">Taiwan Dollar</option> 
8        <option value="THB">Thai Baht</option> 
9    </select> 
10    <input type="button" id="demo_go" value="Get Data"
11 
12    <table cellspacing="0"
13    <caption>Inventory</caption> 
14    <thead> 
15        <tr> 
16            <th>SKU</th> 
17            <th>Item</th> 
18            <th>Price (USD)</th> 
19            <th>Price (<span>USD</span>)</th> 
20        </tr> 
21    </thead> 
22    <tbody> 
23        <tr><td colspan="4">Click <em>Get Data</em></td></tr> 
24    </tbody> 
25    </table> 
26</div> 
view plain | print | ?

Full Code Listing

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

1YAHOO.util.Event.onDOMReady(function () { 
2 
3// Set up some shortcuts 
4var JSON  = YAHOO.lang.JSON, 
5    Dom   = YAHOO.util.Dom, 
6    Event = YAHOO.util.Event, 
7    Demo; 
8 
9// To avoid a Safari issue with JSON reviver adding properties 
10JSON.useNativeParse = false
11 
12Demo = YAHOO.namespace('demo').JSONReviver = { 
13    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}, 
14 
15    currency : 'USD'
16 
17    formatCurrency : function (amt) { 
18        amt += amt % 1 ? "0" : ".00"
19        return amt.substr(0,amt.indexOf('.')+3); 
20    }, 
21 
22    convert : function (k,v) { 
23        // 'this' will refer to the object containing the key:value pair, 
24        // so this will add a new object member while leaving the original 
25        // in tact (but formatted to two decimal places).  If the original 
26        // is not needed, just return the converted value. 
27        if (k === 'Price') { 
28            var x = Math.round(v * Demo.rates[Demo.currency] * 100) / 100; 
29            this.convertedPrice = Demo.formatCurrency(x); // added to item 
30            return Demo.formatCurrency(v); // assigned to item.Price 
31        } 
32        return v; 
33    }, 
34 
35    updateTable : function (inventory) { 
36        var demo       = Dom.get('demo'), 
37            tbl        = demo.getElementsByTagName('table')[0], 
38            tbody      = tbl.getElementsByTagName('tbody')[0], 
39            col_header = tbl.getElementsByTagName('span')[0], 
40            tmp        = document.createElement('div'), 
41            html       = ["<table><tbody>"],i,j = 1,l,item; 
42 
43        // Update the column header 
44        col_header.innerHTML = Demo.currency; 
45 
46        if (inventory) { 
47            for (i = 0, l = inventory.length; i < l; ++i) { 
48                item = inventory[i]; 
49                html[j++] = '<tr><td>'
50                html[j++] = item.SKU; 
51                html[j++] = '</td><td>'
52                html[j++] = item.Item; 
53                html[j++] = '</td><td>'
54                html[j++] = item.Price; 
55                html[j++] = '</td><td>'
56                html[j++] = item.convertedPrice; 
57                html[j++] = '</td></tr>'
58            } 
59        } else { 
60            html[j++] = '<tr><td colspan="4">No Inventory data</td></tr>'
61        } 
62        html[j] = "</tbody></table>"
63 
64        tmp.innerHTML = html.join(''); 
65 
66        tbl.replaceChild(tmp.getElementsByTagName('tbody')[0], tbody); 
67    } 
68}; 
69 
70Event.on('demo_go','click'function (e) { 
71 
72    var self = this,     // Cache this for the async callback closure 
73        sel  = Dom.get('currencies'); // Store the requested currency 
74 
75    // Disable the button temporarily 
76    this.disabled = true
77 
78    // Store the requested currency 
79    Demo.currency = sel.value; 
80 
81    YAHOO.util.Connect.asyncRequest('GET','assets/data.php',{ 
82        timeout : 3000, 
83        success : function (res) { 
84            var inventory; 
85            try { 
86                inventory = JSON.parse(res.responseText,Demo.convert); 
87 
88                Demo.updateTable(inventory); 
89            } 
90            catch(e) { 
91                alert("Error getting inventory data"); 
92            } 
93            finally { 
94                self.disabled = false
95            } 
96        }, 
97        failure : function () { 
98            alert("Error getting inventory data"); 
99        } 
100    }); 
101}); 
102 
103}); 
view plain | print | ?

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: Logging and debugging is currently turned off for this example.

Reload with logging
and debugging enabled.

More JSON Utility Resources:

Copyright © 2009 Yahoo! Inc. All rights reserved.

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