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

Logger Console

INFO 0ms (+0) 8:25:34 AM:

global

Logger initialized

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

Reload with logging
and debugging disabled.

More JSON Utility Resources:

Copyright © 2009 Yahoo! Inc. All rights reserved.

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