I am trying to get the contents of an arraycollection to print out using my debug function (which takes a string). Anyone know how to do this? I would like it would be rather easy but can't seem to find a way...I get the word "Object" printed a lot of the time.
It's a lot cleaner to do:
var str:String = '['+myArrayCol.source.join(', ')+']';
the source property of an ArrayCollection is an Array, so all the usual functions are available.
The following method should get you what you need:
public static function arrayCollectionToString( arr:ArrayCollection ):String
{
var toRet:String = "[";
for each( var obj:Object in arr ) {
toRet += obj.toString() + ", ";
}
toRet += "]";
return toRet;
}
If you stick this in the same class as your debug method, you could then use it as follows:
SomeDebugClass.dbgMessage( SomeDebugClass.arrayCollectionToString( myArrayCollection ) );
Default is allready coma separated
array.toString()
You can use
ObjectUtil.toString(arrayCollection);
Related
I receive the following error when I try to run my code. I haven't managed to solve it yet, please Help:
edit: Marked with * where it fails.
>
public IQueryable<Video> GetVideos([QueryString("id")] int? categorieId)
{
var _db = new TeleviziuneAcademicaAspSilverlight.Models.VideoContext();
IQueryable<Video> query = *_db.Videos;*
if (categorieId.HasValue && categorieId > 0)
{
query = query.Where(v => v.CategorieID == categorieId);
}
return query;
Change
IQueryable<Video> query =
to
IQueryable<Appname.Models.Video> query =
The reason for your error is that you have the type Video defined twice and because of using a short type name you accidentally reference not the one Video you should.
Also change it in the method's return value
public IQueryable<Appname.Models.Video> GetVideos( ... )
You seem to have two classes called Video. If you need both, you'll need to project from one to the other before your return statement:
return query.Select(dbVideo => new Appname.Video()
{
Prop1 = dbVideo.Prop1,
Prop2 = dbVideo.Prop2,
// etc.
});
Though you'll probably need to change the return type to an IEnumerable<> if you do that.
If you can just work with Appname.Models.Video, change IQueryable<Video> to IQueryable<Appname.Models.Video> in the method signature and the method body.
Let's say I have a class which looks like this :
public class MyClass
{
public var attribute1;
public var attribute2;
}
and I'd like to get attribute1 and attribute2 as strings. I tried this :
var test:MyClass = new MyClass();
for (var key:String in test)
{
trace(test[key]);
}
but it does not work, it never goes in the loop. How can I do what I want to do ?
Thanks
A for..in loop enumerates only dynamically added properties. Declared variables and methods of classes are not enumerated in for..in loops. This means that most classes in the ActionScript API will not display any properties in a for..in loop.
For a solution read:
http://livedocs.adobe.com/flex/3/html/help.html?content=usingas_8.html
You'll need to use AS reflection/introspection.
The native way is using describeType function, like this:
public function getDetails():void {
var classInfo:XML = describeType(button1);
// List the class name.
ta1.text = "Class " + classInfo.#name.toString() + "\n";
// List the object's variables, their values, and their types.
for each (var v:XML in classInfo..variable) {
ta1.text += "Variable " + v.#name + "=" + button1[v.#name] +
" (" + v.#type + ")\n";
}
}
(from flex doc: http://livedocs.adobe.com/flex/3/html/help.html?content=usingas_8.html)
I'm not sure but I think the class mx.utils.ObjectUtil can make it simpler. And it's still native way.
Another option is using a library to make it easier.
Look this one: http://www.as3commons.org/as3-commons-reflect/introduction.html
I have 2 dynamic objects and I want to build one to contain all the properties:
var o1:Object = {prop1:val1,prop2:val2,prop3:val3};
var o2:Object = {prop3:val3a,prop4:val4};
and I need to obtain a third object that looks like that:
{prop1:val1, prop2:val2, prop3:val3a, prop4:val4};
Basically I need a way to iterate through the object properties and to add new properties to the third object. I have to mention I'm quite new to AS3/Flash/Flex.
First question, do you really mean to have prop3 in both objects? you will need to decide what to do in case of a collision like that, which object has precedence.
Secondly, check out the introspection apis: http://livedocs.adobe.com/flex/3/html/help.html?content=usingas_8.html
something like this should work:
public function mergeDynamicObjects ( objectA:Object, objectB:Object ) : Object
{
var objectC:Object = new Object();
var p:String;
for (p in objectA) {
objectC[p] = objectA[p];
}
for (p in objectB) {
objectC[p] = objectB[p];
}
return objectC;
}
If the property exists in A and B, B's will overwrite A's. Also note that if the values of a property is an object, it will pass a reference, not a copy of the value. You might need to clone the object in those cases, depending on your needs.
Note: I haven't actually tested the above, but it should be close. Let me know if it doesn't work.
Updated to fix the errors. Glad it works for you though.
You can dynamically access/set properties on objects with the index operator. The for loop will itterate over the property names, so if you put it all together, the following test passes:
[Test]
public function merge_objects():void {
var o1:Object = {prop1:"one", prop2:"two", prop3:"three"};
var o2:Object = {prop3:"threeA", prop4:"four"};
var o3:Object = new Object();
for (var prop in o1) o3[prop] = o1[prop];
for (var prop in o2) o3[prop] = o2[prop];
assertThat(o3.prop1, equalTo("one"));
assertThat(o3.prop2, equalTo("two"));
assertThat(o3.prop3, equalTo("threeA"));
assertThat(o3.prop4, equalTo("four"));
}
you can iterate over the object properties like:
var obj1:Object = new Object();
for(var str:String in obj2){
obj1[str] = "any value"; // insert the property from obj2 to obj1
}
When Flex Sees Something Like This:
<mx:Label text="Hello {MyVar} World!"/>
It Must Translate That Somehow Into ActionScript. But What If I Need To Do Something Similar, At Runtime. How Can I Accomplish What DYNAMICALLY? WHEN I DO NOT KNOW THE CONTENTS OF THE BINDING TEMPLATE.
In ActionScript it would need it to look something like this:
public function CustomDynamicBinding(StringToBind:String):Label {
// *EXAMPLES* Of StringToBind:
// "Hello {MyVar} World!"
// "Product: {name} ${price}.00"
// "{data.label}, {data.description}"
// I've Written It This Way Because I DO NOT KNOW The Exact Text To Be Bound At Design Time.
[Bindable]
var Lab:Label=new Label();
Lab.text=???
return(Lab);
}
How can I accomplish this kind of "Dynamic" binding... Where I don't know the value of "StringToBind" until runtime? For the purposes of this question we can assume that I do know that any variable(s) mentioned in "StringToBind", are guaranteed to exist at runtime.
I already realize there are much more straightforward ways to accomplish this exact thing STATICALLY, and using only Flex/MXML. It's important for my project though that I understand how this could be accomplished without MXML.
Doing This:
lab.text = stringToBind.replace("{myVar}", str);
Will NOT work because this simply assigns ONCE the value of "{myVar}" - (which may not even BE the variable referenced in "stringToBind"!!) to the label, and does not take into account when and if myVar changes! Wouldn't I need to somehow use something Like bindProperty?
Use BindingUtils.bindSetter
var stringToBind:String = "Hello {myVar} World!";
[Bindable]
var myVar:String = 'Flex';
var lab:Label = new Label();
BindingUtils.bindSetter(labelValue, this, "myVar");
function set labelValue(str:String):void
{
lab.text = "Hello " + str + " World!";
//or if you want it dynamic
lab.text = stringToBind.replace("{myVar}", str);
}
Note that this is not pure ActionScript in its strict sense as data binding itself is a Flex concept; this is just MXML-less syntax of doing it. You're still using Flex binding internally - but again, use of Label alone makes if Flexy
private function _BindingSource_bindingsSetup():Array
{
var result:Array = [];
result[0] = new mx.binding.Binding(this,
function():String
{
var result:* = "Hello " + (MyVar) + " World!";
return (result == undefined ? null : String(result));
},
null,
"_BindingSource_Label1.text"
);
return result;
}
It's only a part of generated code. Feel free to add -keep-generated-actionscript parameter to compiler options and read all generated ActionScript in bin-debug\generated.
Disclosure: shameless self promotion
The BindageTools library provides an intuitive builder API for setting up bindings in ActionScript.
OK I am looping through the properties in an object like so:
private var _propsList:Object = {'Type':'product_type'
,'Kind':'product_type_sub'
,'Stone':'primary_stone'
,'Stone Color':'primary_stone_sub'
,'Metal':'metal_type'
,'Brand':'product_brand'};
for(key in _propsList)
{
val = _propsList[key];
trace(key +" = "+ val);
}
I am expecting the first trace to be Type = property_type since that is the first one defined in the array, however it is coming up random everytime. I guess this is because my keys are strings and not integers, however is there a way to specify the order it loops through them?
Thanks!!
You can't rely on for (v in someObject) ... to return things in a predictable order, no.
Depending on your specific situation, you could just use an array to hold the keys, and just iterate through that:
private var keys:Array = ["Type", "Kind", "Stone", "Stone Color", "Metal", "Brand"];
private function iterate():void
{
for each (var k:String in keys)
{
trace(_propsList[k]);
}
}
Maybe a bit obvious or non-elegant, but it'd get the job done. :)
you could hack it by classing-out your "_propsList" object creating an array inside of the newly created PropsList class that references the properties in order. At that point, you could run a FOR loop on the array and get your properties in order.
OR, you could have a function inside that new class that would return an Array of those properties. like this:
public function getProps():Array {
return [myPropertyOne, myPropertyTwo, myPropertyThree];
}
In general, I think this is a case where you shouldn't depend on a particular behavior from the framework/language you are using. This type of behavior is generally poorly documented and can change from version to version.
If you really need a specific retrieval order, I would create a wrapper class as jevinkones suggested above. Maybe there's even a utility class in the framework somewhere to accomplish this (Dictionary, etc.?)
HTH,
Karthik
I found this link that gives some background:
Subtle Change in for..in Loops for ActionScript 3
This question is actually a dup of this one.
How about using an array representation like this:
var _propsList:Array = [
['Type', 'product_type'],
['Kind', 'product_type_sub'],
['Stone', 'primary_stone'],
['Stone Color', 'primary_stone_sub'],
['Metal', 'metal_type'],
['Brand', 'product_brand']
];
for(var i in _propsList) {
var elem = _propsList[i];
var key = elem[0];
var val = elem[1]
}