There are many articles out there explaining what JSON is and where to use it, including a very good article written by Scott Good titled JSON and Domino.
What I’m going to try to explain in this tutorial is why associative arrays are our best friend when coding with JSON and Ajax. We have all seen how JSON is starting to dominate the Ajax calls. Face it, XML is so 2006. But let’s jump to the code shall we?
Normal Arrays
We made an Ajax call to our table, or view if we live in the Lotus Domino world, using our favorite way (mine is using the Dojo toolkit) and we now have an array of objects that we need to iterate through. Let’s see an example of what the array might look like.
var aArray = [
{unid: "111AAABBBCCCDDD111", first: "Rob", last: "Novak", phone: "(555) 111-1111", zipcode: "11111"},
{unid: "222AAABBBCCCDDD222", first: "Troy", last: "Reimer", phone: "(555) 222-2222", zipcode: "22222"},
{unid: "333AAABBBCCCDDD333", first: "Jerald", last: "Mahurin", phone: "(555) 333-3333", zipcode: "33333"}
];
If all we want to do is write the array out to the browser this is fine, we just use a normal for loop.
var sHTML = '<table border=1>';
for (var i = 0; i < aArray.length; i++){
sHTML += '<tr>';
sHTML += '<td>' +
aArray[i].unid + '</td>'
;
sHTML += '<td>' +
aArray[i].first + '</td>'
;
sHTML += '<td>' +
aArray[i].last + '</td>'
;
sHTML += '<td>' +
aArray[i].phone + '</td>'
;
sHTML += '<td>' +
aArray[i].zipcode + '</td>'
;
sHTML += '</tr>';
}
sHTML += '</table>';
document.write(sHTML);
Output:
111AAABBBCCCDDD111 | Rob | Novak | (555) 111-1111 | 11111 |
222AAABBBCCCDDD222 | Troy | Reimer | (555) 222-2222 | 22222 |
333AAABBBCCCDDD333 | Jerald | Mahurin | (555) 333-3333 | 33333 |
But what if we have a little bit more complex example. (Stay with me.) What if we had a way of updating user meta data from this document or form and later call code on the server to actually update the record or document in the back-end.
So we have created JavaScript that when a row is clicked, fields are populated with data from the array so the user can update them. The end user clicks a button and our array should be updated with the new meta data. We also want to add a property of “updated” with a value of true (boolean) if it is changed so that we later only pass in those documents that have changed to our back-end code (agent if Lotus Domino).
So in our scenario we have updated one of the records and call a function to update the array. With a normal array this would be done like this.
function updateUserMetaData(sUnid, sFirst, sLast, sPhone, sZip){
for (var i = 0; i < aArray.length; i++){
if(aArray[i].unid == sUnid){
aArray[i].first = sFirst;
aArray[i].last = sLast;
aArray[i].phone = sPhone;
aArray[i].zipcode = sZip;
aArray[i].updated = true;
break;
}
}
}
This works but if we have hundreds or thousands of records in the array it can take a long time. We have to iterate over all the values in our array to find the one with the right “unid”. Even though we are using a break statement when we have found our record it can still take a long time. Associative arrays to the rescue.
Associative Arrays
In JavaScript we have something called objects. They are a mapping from property names to values. Objects are an associative array with one caveat: since property names are strings, only string keys are allowed. That doesn’t matter to us.
We write an object literal as { property1: value1, property2: value2, ... }
Let’s rewrite our code to create an object instead of the array above.
var oObject = {
"111AAABBBCCCDDD111": {first: "Rob", last: "Novak", phone: "(555) 111-1111", zipcode: "11111"},
"222AAABBBCCCDDD222": {first: "Troy", last: "Reimer", phone: "(555) 222-2222", zipcode: "22222"},
"333AAABBBCCCDDD333": {first: "Jerald", last: "Mahurin", phone: "(555) 333-3333", zipcode: "33333"}
};
Can you see the difference? Not much difference in the text but a huge difference in what we can do.
First we can’t use a normal for loop to write our table any more. We need to use a for(in) loop.
var sHTML = '<table border=1>';
for (var unid in oObject){
sHTML += '<tr>';
sHTML += '<td>' + unid + '</td>';
sHTML += '<td>' + oObject[unid].first + '</td>';
sHTML += '<td>' + oObject[unid].last + '</td>';
sHTML += '<td>' + oObject[unid].phone + '</td>';
sHTML += '<td>' + oObject[unid].zipcode + '</td>';
sHTML += '</tr>';
}
sHTML += '</table>';
document.write(sHTML);
The output is exactly the same as above so we haven’t gained any value there. The big difference is in our function to update our meta data.
function updateUserMetaData(sUnid, sFirst, sLast, sPhone, sZip){
oObject[sUnid].first = sFirst;
oObject[sUnid].last = sLast;
oObject[sUnid].phone = sPhone;
oObject[sUnid].zipcode = sZip;
oObject[sUnid].updated = true;
}
As you can see we no longer need to iterate through an array to find our record. Since it is an object we can just update the property values directly.
Conclusion
In search for fast JavaScript code, associative arrays will help many times. It may seem a little difficult to code to begin with but after a while it actually makes much more sense. Object oriented programmers will find it easier.
Exactly one year ago from today, June 6th 2006, James Mc Parlane declared JavaScript Array and Object.prototype Awareness Day. Read that article. It will help you code better associative arrays (objects) in JavaScript.
I think I’d be wary of such a sweeping statement. Surely an object is only a associative array if you use the new Array() constructor. Objects created using the object literal are just good old fashioned objects.
Describing them as Associative Arrays opens you up for people crying foul and quoting…
ajaxian.com/archives/javascript-associative-arrays-considered-harmful
www.andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
Type of recent postings on the subject.
JP –
OK, we can argue if it should be called an associate array or not but the purpose of the tutorial is to show low to medium level JavaScript coders the benefits of objects compared to number based arrays.
Very well.
Thanks!