How to access to Object property When the propety I want to access to it's in a String variable - apache-flex

It's too complicate to explain but I'll give you an example
I have an AS3 ResultEvent Object
and this object has several propeties which can be accessed by this like:
event.result.name or event.result.age .....
and, I have this String variable: eventProperty:String that contains "name" or "age"
How do I access to event.result. with the variable?
thank you.

The ActionScript (or ECMAScript) . operator is just syntactic sugar, useful but not really needed. For what you want to do you can use the normal object property access operator [].
So you have to do it like this event.result[ eventProperty ].
Good luck,
Alin

You should probably move your ResultEvent object into an actual Object type first. Then you can access the properties via the object. If your object is an arraycollection, make sure to immediately pass the ResultEvent into an arraycollection since you cannot cast it as you normally might (ArrayCollection)ResultEvent. Here is how to throw the result into an object:
var yourObjectName:Object = event.result;
and here is how to throw it into an arraycollection if you need to:
var yourArrayCollection:ArrayCollection = event.result as ArrayCollection;

Related

Can I cast a string object passed on command line argument to the actual object?

Is it possible to cast a command-line passed string object back to actual object?
I want to do the following, but throwing error can't cast.
Button objPro = (Button) sender;
cProduct cp = (cProduct) objPro.CommandArgument;
If no, then why?
This is what the string holds.
cProduct cpObj = (cProduct)e.Row.DataItem;
Button btnAddProduct = (Button)e.Row.FindControl("btnAddProduct");
if (btnAddProduct != null)
{
btnAddProduct.CommandArgument = cpObj.ToString();
}
You probably can't, because it's a string. It's not a cProduct (whatever that is - consider following .NET naming conventions and naming it Product instead).
Now you could do this if you had a explicit conversion operator in cProduct to create an instance from a string.
You haven't really explained what's in the string, or what's in the type - but if your cProduct type provides a ToString method which contains all the data in a reversible form, then you could easily write a method or a constructor to create the product again:
Product product = new Product(objPro.CommandArgument);
or maybe:
Product product = Product.Parse(objPro.CommandArgument);
You'll have to write that constructor/method, of course.
I would strongly recommend using a constructor or method instead of an operator, just to keep your code clearer - it's very rarely a good idea to write your own conversion operators.
Take a look at CommandArgument on MSDN. The property is a string, when you assign the a value to the property, you aren't casting some complex type to string, you are setting a string value on the property. Can you cast a string back to your object type anyway, regardless of it being a CommandArgument. I doubt it. If the argument is an int you could try int.Parse or similar for other types which have a parse method.

How to set an empty Object's properties programatically?

I'm doing some Actionscript work right now and I'd like to know whether there's a way to initiate an empty object's value programatically like this:
var myObj:Object = new Object;
myObj.add("aKey","aValue");
To add a property called aKey whose value is aValue
I need to create a "Dumb" (data-only) object to use as a parameter to send via POST. So I don't know offhand how long and/or how many attributes it's gonna have.
Or something like that.
Thanks
ActionScript 3 allows you to create new Objects using an expressive Object Literal syntax similar to the one found in JavaScript:
const myObj : Object = {
aKey: "aValue",
};
trace(myObj.aKey); // "aValue"
If you want to assign properties after the object has been constructed then you can use either dot notation or square bracket notation, eg:
const myObj : Object = {}; // create an empty object.
myObj.aKey = "aValue";
myObj["anotherKey"] = "anotherValue";
If you plan on sending the data over HTTP, you may wish to consider looking at the URLVariables class which will take care of URL encoding the data for you.

What's the best way to use hamcrest-AS3 to test for membership in an IList?

I'm using Flex 3.3, with hamcrest-as3 used to test for item membership in a list as part of my unit tests:
var myList: IList = new ArrayCollection(['a', 'b', 'c']).list;
assertThat(myList, hasItems('a', 'b', 'c'));
The problem is that apparently the IList class doesn't support for each iteration; for example, with the above list, this will not trace anything:
for each (var i: * in myList) { trace (i); }
However, tracing either an Array or an ArrayCollection containing the same data will work just fine.
What I want to do is (without having to tear apart my existing IList-based interface) be able to treat an IList like an Array or an ArrayCollection for the purposes of testing, because that's what hamcrest does:
override public function matches(collection:Object):Boolean
{
for each (var item:Object in collection)
{
if (_elementMatcher.matches(item))
{
return true;
}
}
return false;
}
Is this simply doomed to failure? As a side note, why would the IList interface not be amenable to iteration this way? That just seems wrong.
You will have to create a custom Matcher that's able to iterate over an IList. More specifically, extend and override the matches method of IsArrayContainingMatcher that you reference above (and you'll probably want to create IList specific versions of hasItem and hasItems as well). A bit of a pain, but perhaps it's worth it to you.
Longer term, you could file an issue with hamcrest-as3 (or fork) to have array iteration abstracted using the Iterator pattern. The right Iterator could then be chosen automatically for the common types (Proxy-subclasses, IList) with perhaps an optional parameter to supply a custom Iterator.
For the main issue: Instead of passing the ArrayCollection.list to assertThat(), pass the ArrayCollection itself. ArrayCollection implements IList and is iterable with for each.
var myList:IList = new ArrayCollection(['a', 'b', 'c']);
assertThat(myList, hasItems('a', 'b', 'c'));
In answer to part two: ArrayCollection.list is an instance of ArrayList which does not extend Proxy and does not implement the required methods in order to iterate with for each. ArrayCollection extends ListCollectionView which does extends Proxy and implements the required methods.
HTH.
I find myself coming back to this every once in a while. Rather than writing new Matchers, I find that the easiest solution is always to just call toArray() on the IList and match against the resulting array.

How to clone an object in Flex?

I want to clone a Canvas object, which contains a Degrafa Surface with several Geometry shapes.
I tried the naive approach:
return ObjectUtil.copy(graph_area) as Canvas;
which resulted in errors:
TypeError: Error #1034: Type Coercion failed: cannot convert Object#63b1b51 to com.degrafa.geometry.Geometry.
TypeError: Error #1034: Type Coercion failed: cannot convert Object#63b1039 to com.degrafa.geometry.Geometry.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at mx.core::Container/addChildAt()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2196]
at mx.core::Container/addChild()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2140] ...
What you want is called a deep copy, generate a new instance with the same information of the original.
The only way I know how to do it is using ByteArray as follows:
private function clone(source:Object):*
{
var buffer:ByteArray = new ByteArray();
buffer.writeObject(source);
buffer.position = 0;
return buffer.readObject();
}
AS3 is really lacking Object.clone()...
ObjectUtil
The static method ObjectUtil.copy() is AS3's "Object.clone()":
public static function copy(value:Object):Object
Copies the specified Object and
returns a reference to the copy. The
copy is made using a native
serialization technique. This means
that custom serialization will be
respected during the copy.
This method is designed for copying
data objects, such as elements of a
collection. It is not intended for
copying a UIComponent object, such as
a TextInput control. If you want to
create copies of specific UIComponent
objects, you can create a subclass of
the component and implement a clone()
method, or other method to perform the
copy.
I found myself trying something more like this alas it still doesn't seem to copy a TextArea (aka UI Object)...
public function duplicateObject(sourceObject:*, targetObject:*):void {
var buffer:ByteArray = new ByteArray();
buffer.writeObject(sourceObject);
buffer.position = 0;
targetObject = buffer.readObject();
}
i got the same problem (for a NamedEntity interface i created), looked for the answer here, but only got it working making a call to the registerClassAlias method (which i took from http://richapps.de/?p=34). Just like that:
public static function clone(namedEntity:NamedEntity):NamedEntity {
registerClassAlias('test',ReflectionUtil.classByObject(namedEntity));
var returnObject:NamedEntity = ObjectUtil.copy(namedEntity) as NamedEntity;
}
I don't think ObjectUtil.copy will work for cloning a canvas.
According to the flex doc :
Copy
This method is designed for copying data objects, such as elements of a collection. It is not intended for copying a UIComponent object, such as a TextInput control. If you want to create copies of specific UIComponent objects, you can create a subclass of the component and implement a clone() method, or other method to perform the copy.

What does this this ActionScript syntax mean? ( Syntax for returning Objects Inline )

I am a Java programmer and need to work on a Flex/ActionScript project right now. I got an example of using ITreeDataDesriptor from Flex 3 Cookbook, but there is one line of actionscript code that's hard for me to understand. I appreciate if someone could explain this a little further.
public function getData(node:Object, model:Object=null):Object
{
if (node is Office) {
return {children:{label:node.name, label:node.address}};
}
}
The part that I didn't understand was "{children:{label:node.name, label:node.address}}". Office is simply a value object that contains two String properties: name and address.
The following return expression (modified from the question) ...
return {children:{label:node.name, body:node.address}}
... is functionally equivalent to this code ...
var obj:Object = new Object();
obj.children = new Object();
obj.children.label = node.name;
obj.children.body = node.address;
return obj;
The anonymous object returned in the question code complicates matters because it defines a property twice. In that case, the first declaration is used, and the subsequent one(s) are ignored. No compile-time or runtime error is thrown.
I think in Java you would call that a map or an associative array. In Javascript and Actionscript you can say this to create an object with certain properties:
var myobject = {
'prop1': 100,
'prop2': {
'a': 1
}
}
trace( myobject.prop1 ); // 100
trace( myobject.prop2.a ); // 1
In your example it's just returned as a nameless object.
return {children:{label:node.name, label:node.address}};
Means you are returning a new Object. The {} are the Object's constructor, and in this case its an Anonymous object.
Thank you both for the quick response. So if I understand your explanations correctly, the return statement is returning an anonymous object, and this object has only one property named "children", which is again an associative array - ok, here is the part I don't quite understand still, it seems that both properties in this array are named "label", is this allowed?

Resources