Create a copy of an object in flex whose constructor has required parameters - apache-flex

When using ObjectUtil.copy() on my object, I get the following error
Argument count mismatch on foo.bar::MyObject(). Expected 1, got 0.
MyObject's constructor takes in one parameter. Is there a way for me to clone, or copy it?

Use the ObjectUtil.clone method. That should do deep copies.
However, I'm not sure if that will solve the issue.
In Flex 4.5 Neither copy, nor clone, create a new version of the object using the new keyword; therefore the constructor is never called. Both do byte array copies. I'd be interested to see your code.

I use:
public static function clone(source:Object):* {
var myBA:ByteArray = new ByteArray();
myBA.writeObject(source);
myBA.position = 0;
return(myBA.readObject());
}
Never let me down.

Related

copy a Collection element by value in C#

In the code below, a reference type is being added. How can i do this value type?
imgList.Items.Add(imgList.Items[0]);
imgList.Items[imgIndex].Data = input; <== **This updates the 0th and the newly added element which is the issues**
Please advise
In order to avoid this issue, you need to clone imgList.Items[0] before adding it to imgList.Items. This basically involves creating a new object of the same type and populating it with data from the original.
The complexity of doing so depends on what the object is, but look at the answers to this question for some tips on cloning objects.
Edit: I forgot that .MemberwiseClone was protected.
You don't say in your code what the type of object is that you're adding to the list. If it's a class of yours, you can add a method to return a copy:
public MyType ShallowCopy()
{
return (MyType)this.MemberwiseClone();
}
and use
imgList.Items.Add(imgList.Items[0].ShallowCopy());
Or you can add a copy constructor:
public MyType(MyType original)
{
// Copy each of the properties from original
this.Data = original.Data;
}
and use
imgList.Items.Add(new MyType(imgList.Items[0]));

TypeError: Error #1034: Type Coercion failed: cannot convert Object#1456c7b9 to mx.messaging.messages.IMessage

Im trying to connect a Flash client to BlazeDS. There has been some success with this from others using the vanilla BlazeDS setup. However I'm using the new Spring BlazeDS Integration from springsource and running aground.
The flash client actually seems to be working in that I can see the correct data in the body of the returned object, but for some reason unknown it fails casting as an IMessage. It fails in PollingChannel.as on this line with the subject line error
var messageList:Array = msg.body as Array;
for each (var message:IMessage in messageList) <--
On application load I register a whole bunch of classes like so
registerClassAlias( "flex.messaging.messages.RemotingMessage", RemotingMessage );
registerClassAlias("mx.messaging.messages.IMessage", IMessage);
etc..
my code is basically
var channelSet:mx.messaging.ChannelSet = new mx.messaging.ChannelSet();
var channel:mx.messaging.channels.AMFChannel = new AMFChannel("my-amf", "http://localhost:8400/SpringA/messagebroker/amf");
channelSet.addChannel(channel);
var consumer:mx.messaging.Consumer = new Consumer();
consumer.channelSet = channelSet;
consumer.destination = "simple-feed";
consumer.subscribe();
consumer.addEventListener(MessageEvent.MESSAGE, test);
private function test(event:IMessage)
{
trace("msg..");
// breakpoint never makes it here
}
I have a flex client which works 100% with same destination/channel.
The error in the title means that you, for some reason, got an object that is not implementing or extending the IMessage interface, therefore the loop can not cast it in this part:
for each (var message:IMessage in messageList){
Either you should somehow make sure that you don't add anything that is not extending or implementing IMessage, or check if the variable IS actually ext./imp. it. Also - if you want to do that, you will have to change the for each like this:
for each (var obj in messageList){
if (obj is IMessage){
var message:IMessage = obj as IMessage;
// DO STUFF HERE
}
}
Add this Object mapping:
registerClassAlias("flex.messaging.io.ObjectProxy", ObjectProxy);
If on your Java VO objects you have overridden the hashcode() method, this situation could happen.
Remove the hashcode() override (if you are able to).
See my blog for the backstory on how I discovered this. http://squaredi.blogspot.com/2013/12/remoting-landmine-without-stack-trace.html
I had the same error when trying to send an actionscript object to the backend. My problem was that my c# equivalent object was missing an public parameterless constructor.

Image to Object with as3

I'm trying to convert an image in my assets folder
"./assets/image1.png"
to type Object. It needs to be Object because that's what the function I'm using it in is expecting.
Any ideas what would be the simplest way to do this?
Do you mean something like :
[Embed(source="assets/logo.jpg")]
private var logo:Class;
private function init(e:Event):void
{
this.displayImage(logo as Object);
}
private function displayImage(img:Object):void
{
//Assuming you have an image control on stage with an instance
//name of "myImage"
myImage.source = img;
}
If the function you are passing the image to is expecting an Object object, you can in pass anything, it won't reject it. That doesn't mean the function will work correctly, though. Any value will be an Object (except for undefined, which will be accepted but coerced to null and maybe some other strange cases).
So, assuming you didn't write the function yourself, do you have any doc that describes what it expects? Or maybe you have the source code for it?. Otherwise, if the only thing you know about what this function expects is that the parameter must be of type Object... you're in trouble, I think.
Why don't you create a new Object containing the information about the image... including the path.
var obj:Object = new Object();
obj.path = "/assets/image.jpg";
obj.height = 32;
obj.width = 32;
trace(obj.path);
// or, if Flex
Alert.show(obj.path);
And then just pass the new Object into the function and access it like I have above.

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