views:

83

answers:

1

In order to send a POST request I need to enumerate all properties of a given object. This object may or may not be dynamic. I'm looking for the most elegant solution. This is what I've got so far:

    function createURLVariables(params:Object):URLVariables
    {
        // Workaround: Flash Player performs a GET if no params are passed
        params ||= {forcePost: true};
        var vars:URLVariables = new URLVariables();
        var propertyName:String;
        var propertyList:XMLList = describeType(params)..variable;
        var propertyListLength:int = propertyList.length();
        // A dynamic object won't return properties in this fashion
        if (propertyListLength > 0)
        {
            for (var i:int; i < propertyListLength; i++)
            {
                propertyName = propertyList[i].@name;
                vars[propertyName] = params[propertyName];
            }
        }
        else
        {
            for (propertyName in params)
                vars[propertyName] = params[propertyName];
        }
        return vars;
    }

One potential problem is that this won't return properties for getters (accessors).

+6  A: 

I took the following approach in the as3corelib JSON Encoder. You'll have to modify this to suit your needs, but it should give you an idea to work from. Note that there is some recursion in here (the convertToString call, which you might not need:

/**
 * Converts an object to it's JSON string equivalent
 *
 * @param o The object to convert
 * @return The JSON string representation of <code>o</code>
 */
private function objectToString( o:Object ):String
{
    // create a string to store the object's jsonstring value
    var s:String = "";
    // determine if o is a class instance or a plain object
    var classInfo:XML = describeType( o );
    if ( [email protected]() == "Object" )
    {
        // the value of o[key] in the loop below - store this 
        // as a variable so we don't have to keep looking up o[key]
        // when testing for valid values to convert
        var value:Object;

        // loop over the keys in the object and add their converted
        // values to the string
        for ( var key:String in o )
        {
            // assign value to a variable for quick lookup
            value = o[key];

            // don't add function's to the JSON string
            if ( value is Function )
            {
                // skip this key and try another
                continue;
            }

            // when the length is 0 we're adding the first item so
            // no comma is necessary
            if ( s.length > 0 ) {
                // we've already added an item, so add the comma separator
                s += ","
            }

            s += escapeString( key ) + ":" + convertToString( value );
        }
    }
    else // o is a class instance
    {
        // Loop over all of the variables and accessors in the class and 
        // serialize them along with their values.
        for each ( var v:XML in classInfo..*.( 
            name() == "variable"
            ||
            ( 
                name() == "accessor"
                // Issue #116 - Make sure accessors are readable
                && attribute( "access" ).charAt( 0 ) == "r" ) 
            ) )
        {
            // Issue #110 - If [Transient] metadata exists, then we should skip
            if ( v.metadata && v.metadata.( @name == "Transient" ).length() > 0 )
            {
                continue;
            }

            // When the length is 0 we're adding the first item so
            // no comma is necessary
            if ( s.length > 0 ) {
                // We've already added an item, so add the comma separator
                s += ","
            }

            s += escapeString( [email protected]() ) + ":" 
                    + convertToString( o[ v.@name ] );
        }

    }

    return "{" + s + "}";
}
darronschall
That's a great starting point, thanks! Going to leave the question open for a while in case somebody else has something to add.
Franky-D
+1 for a great encoder / decoder and for using describeType. I use this lib all the time. Kudos.
sberry2A