Sunday, May 25, 2008

A simple .toJSON() method

Here's an interesting situation we've stumbled across in recent development. Now, bear in mind, I'm not the world's greatest Javascript developer -- not by a longshot -- but I seem to get the job done, so if there's a way to improve upon this, I'm definitely interested.

The simple AJAX function we're using has a an event handler that we use to deal with intermittent network problems. Instead of having the script bomb out when the server is busy, we want it to wait a few moments, then try the call again.

Part of the problem with this is that by the time our script has picked up the error, it has already moved on to other things, so the object that we used to set the server request variables is no longer available. How do you pass these "retry" parameters to an onError event handler that is called from a setTimeout() function?

The method I came up with is quite the eclectic mix of code. What we need to do is take the object that contains all our parameters and convert it to a string so that we can pass it back to the AJAX function as a regular parameter. This is how I've done it:


// Function converts a JSON object to string literal for passing
// into externally referenced callbacks (a la on AJAX failure retries)
Object.prototype.toJSON = function () {
// We first need to declare an array to hold each propertyName/value pair
var result = [];

// Now iterate through each property and assign them to the array
for(var element in this){
var key;
var val;

// Prepare the object property names...
// encapsulate strings in quotes,
// let numbers go unscathed,
// recurse if it's an embedded object,
// skip everything else
if (typeof element == "string") {
key = "'" + element + "'";
} else if (typeof element == "number") {
key = element;
} else if (typeof element == "object") {
key = element.toJSON();
} else {
continue;
}
// Do the same for the object values
if(typeof this[element] == "string"){
val = "'" + this[element] + "'";
} else if (typeof this[element] == "number") {
val = this[element];
} else if (typeof this[element] == "object") {
val = this[element].toJSON();
} else {
continue;
}
// Add the most recent name/value pair to the result array
result.push(key + ":" + val);
}
// Send the properly formatted string back to the script
// We do this by concatenating the elements together into a string
result = "{ " + result.join(", ") + " }";
return(result);
};

For the uninitiated, this is a method prototype extension. It works just like a .toString() call would. For example:


var testObj = { 'var1':0, 'var2':'sampleText', 'var3':12345 };
var testStr = testObj.toJSON();


The testStr variable now holds the contents of testObj, but as a string literal, so that we can pass it around wherever (or, more accurately, whenever) we want.

Again, I'm sure there's a lot of room for improvement here, but it serves the purpose we need, so I'm not going to beat myself up if someone shows me a cleaner way.

I have seen a couple alternatives that rely on a completely different approach, but I have yet to try them (partly because it appears that using them would require a significant review of our AJAX functions).

What I like most about this little method is that it's smart enough to handle nested objects. What I don't like is that it's long, and easily bombs out if the object being referenced is not a true object (but instead, say, a string variable). This is something I could fix in the future, but I would instead just say, "Don't do that!" (Because it means less work for me.) :)

(Note: the tabs for indentation don't turn out real well here. I'll have to find a fix for that.)

Saturday, May 24, 2008

The Search for Unity (Updated)

First, let me say that busy is an understatement, so it's (obviously) been quite a while since my last update. This is a short but sweet segue into an entry of mine from last summer about being able to access everything digital from one central device and location.

The quick answer is that applications for Windows Mobile 6 have been the answer to most of my prayers.

First and foremost, you may recall that our corporate solution for groupware is Lotus Notes. This makes us a little unconventional and finding helper applications becomes a little more difficult, but alas, it's what we're stuck with. For this, I've found a perfect solution: Commontime mNotes. It seamlessly synchronizes my e-mail, contacts, calendar, and to-do list with the built-in WM6 counterparts. I even get the little buzzes and chimes for meeting alerts. (Without them, I'd be late to every meeting I'm supposed to attend -- if I even remembered them at all.)

The downfall of Commontime mNotes is the $15.00 monthly service fee, but it's a small price to pay to free yourself from the shackles of your desktop PC.

Next on my list of groovy things is an old stand-by: IMAP e-mail. Thankfully, most e-mail services now have an IMAP option, and all of the ones I use are free. Yahoo, MSN, and Google Mail all have direct IMAP mail access for free, so I can access all three services from the messaging application on my WM6 device. I set each one up to check my e-mail at varying intervals (my Yahoo and gmail accounts are for personal use, for example, so I only have my phone set up to check those a few times per day). I realize this is nothing new, but it's something that a lot of people forget to do. Why bother logging into a desktop PC when all you want to do is read your joke of the day or send a quick note to Aunt Bunny telling her she has a mustache?

These two simple things have shortened the amount of time I spend at my desk more than I could have imagined. More convenient is the fact that my phone has a full qwerty keyboard, so composing e-mail is not much of an issue. I also happen to spend nearly 3 hours per day commuting, which gives me ample time to check my schedule and fire off a couple quick e-mails. (Yes, I'm "that guy," but I'm responsible about it -- I wait until I'm on the limited access highway and I'm not in a group of other vehicles before pulling out my PocketPC.)

Now, bear in mind that without a data plan, all of this stuff is pretty much worthless unless you're in a Wi-Fi area -- which doesn't happen for us normal folks very often.

All of that said, I still have a long way to go to restore my sanity, but things are definitely looking better, and I'm hoping to pass along another update in short order with some other tips for simplifying your connected presence.