17
Apr
2008

Over the past few months I've been lucky enough to have the opportunity to start playing around with Flex at work. Overall it's been a pretty good experience. I think Flex itself is a very cool technology, and FlexBuilder absolutely ROCKS as an IDE. Of course, there have been hurdles. Some I was able to overcome pretty easily, and some left scars. I figured I'd post some of them here and hopefully save some other Flex n00bs the hassle of figuring things out the hard way.

The application that I'm currently working on is fairly straightforward. Let's call it a user manager. I present a couple of comboboxes that let the user filter by certain criteria (state, zipcode, etc) and populate a DataGrid with the list of users that were returned.

I chose to pass these values in a single object. In ColdFusion, this single object would be a structure. Flex, or more appropriately, ActionScript, has a comparable datatype, simply called Object. an Object would be created as follows:

var args:Object = new Object();
args.stateCode = "CA";
args.zipCode = "94583";
args.territory = 3;

Fairly straightforward when compared to a ColdFusion structure:

<cfset args = structNew() />
<cfset args.stateCode = "CA" />
<cfset args.zipCode = "94583" />
<cfset args.territory = 3 />

All well and good. The hitch was, I didn't want to enable the submit button unless the end user had chosen at least one of the filter criteria. An unfiltered search would return an unwieldy amount of records. Because an Object (much like a structure) is simply an associative array, my first attempt was to reference the Object's length property. Small problem. There is no length property.

Where a ColdFusion structure has functions such as structIsEmpty(), there is no corresponding function to an ActionScript Object. ColdFusion also has structKeyList() and structKeyArray() functions, which could be used in conjunction with listLen() or arrayLen(). Again, no such corresponding functions in ActionScript.

It was suggested that I could use a "for each" loop on the Object and check the properties that way. That worked, and looked something like this:

var numOfArgs:int = 0;
for each (var num in args) {
numOfArgs++
}

Then I simply did a conditional to check that numOfArgs was greater than 0. While this worked, it didn't feel quite "right". Looping seemed inefficient. Maybe I've been spoiled by functions like structIsEmpty(), but I just felt that there had to be a better non-looping way.

I posed the question in #cfflex on IRC's Dalnet. Dan Wilson offered up a few suggestions, but none did the trick. Enter Shannon Hicks. Shannon was able to offer up a solution that worked a treat, without a loop.

numOfArgs = ObjectUtil.compare(stArguments, new Object());

From the docs:

Compares the Objects and returns an integer value indicating if the first item is less than greater than or equal to the second item.

Perfect. I didn't care how many properties (keys) the Object held, I just needed to know if it held any. Comparing my Object to a newly created Object (which would be empty by default) gave me what I needed.

This wasn't without a teeny hurdle either... being a ColdFusion developer, I'm not used to having to import libraries. All of ColdFusion's built in functions are available by simply calling the function. in ActionScript, functions are grouped into libraries, and libraries aren't available to your application unless you specifically make them available to your application.

compare is part of the ObjectUtil library. Since I explicitly called ObjectUtil.compare() (as opposed to just compare()), that was fine. But ObjectUtil is part of mx.utils. So I needed to import the mx.utils library.

At the top of my ActionScript block, i needed to add

import mx.utils.*;

There may be a "better way", but for now this gives me the information that I need without having to loop over my Object. Thanks to Dan and shannon both for their assistance.

Comments (2) | 2430 Views

Related Blog Entries

Comments

Add Comment | Subscribe to Comments

  1. Marty Pitt's Gravatar

    # Posted Marty Pitt on 4/18/08 9:19 AM

    Generally speaking, using Object like that is considered bad practice. It's a trap I fell into when I was new to flex, and wish I hadn't.

    In your example, I'd reccomend you promote to a searchFilter class, which has a method on it called hasCriteria():Boolean

    Your current example leaves the consumer of Object too tightly coupled to its implementation.

    Also, using Dynamic Objects means you lose compile time checking, and that really smarts!

    Just my two cents worth. Welcome to Flex!

  2. Charlie Griefer's Gravatar

    # Posted Charlie Griefer on 4/18/08 1:33 PM

    hi marty:

    thanks for the comment. the searchFilter class sounds like it might be something worth looking into.

    but to clarify something, i wasn't trying to suggest that anything i'm discussing is by any means a "best practice", and i hope it didn't come across as such.

    this is just me (a cf guy) learning flex, and getting familiar with the datatypes that exist, what libraries hold what functions, etc. once i understand those basics of the language, then learning how to best implement what i know would be the next step.

    this is me crawling before i walk. just trying to share what i'm learning along the way :)

Add Comment