im having trouble with the result of a webservice call. When the result comes in and kicks off the resultHandler function i set a break point so i can examine the result. I can see that there are 0 records in the array collection however i can see content so im assuming that the zero is just referring to the first index of the array
the problem happens when i try assign the value to an array collection as follows;
public function resultHandler(event:ResultEvent):void{
var result:ArrayCollection = event.result as ArrayCollection;
the result of this operation is a result var with the value of null. Can anyone explain what could be happening here? thanks a lot
another thing i just noticed is that the result type is mx.utils.ObjectProxy, im expecting an array
If the webservice returns just one element, it will be deserialized as ObjectProxy. You will have to manually convert it into an array.
I'd normally do this after a WS call:
if (event.result is ArrayCollection) {
result = event.result;
}
else {
result = new ArrayCollection([event.result]);
}
Chetan is right -- the cast operation to ArrayCollection is failing, because the source object is not an ArrayCollection. Try this instead:
public function resultHandler(event:ResultEvent):void
{
var ac:ArrayCollection = new ArrayCollection([event.result])
// ...
}
The "as" operator will return null in situations where an exception would occur at runtime -- in your case, casting from ObjectProxy to ArrayCollection. If instead you pass event.result as the sole member of an array (by surrounding it with []), your ArrayCollection will be constructed properly, and you'll be able to retrieve the object normally:
var o:Object = ac.getItemAt(0) as Object;
trace(o.yourObjectProperty.toString());
Hope it helps!
0 records in the array is the length of the array, that actually means 0. If you have something in index 0 of an array, that array has a length of at least 1. It looks like you aren't getting any data back, not even and empty array collection.
The problem in my opinion is that you cannot cast event.result as an array collection, but you have to cast it as an array.
The best practice in this is having a getter and a setter:
private var _acLocation:ArrayCollection=new ArrayCollection;
public function set acLocation(acLocation:ArrayCollection):void{
_acLocation=acLocation;
//do this if you want for exaple to assign the arraycollection to a datagrid dataprovider
dgMyDataGrid.dataProvider=_acLocation;
}
public function get acLocation():ArrayCollection{
return _acLocation;
}
Then in the result handler function of a service call, code
acLocation=new ArrayCollection(event.result as Array);
Hope it helps
Related
Is there a way to check if your session variable contains something... Just like a list has a method "Contains". Is there something similar to that? Some method or something?
Hi you can try casting your session so it can have a type for example
var listofperson = Session["ListofPerson"] as List<string>;
var hasGeorge = listofperson.Contains("George");
When you retrieve items from Session, they are of type System.Object. This means that you don't get any of the actual methods available for the object's real type. You can do so by casting it to the correct type. In this case, it sounds like you're storing a List<string>. So we can use the as operator. If the object is not of that type or was null to begin with, myList will null. Otherwise it will be of the type you specify.
List<string> myList = Session["myKey"] as List<string>();
if(myList == null)
{
//either Session["myKey"] was null or the object wasn't a List<string>
}
else
{
if(myList.Contains("fuzzy puppies"))
{
//your list contains fuzzy puppies
}
else
{
//your list doesn't contain fuzzy puppies
}
}
Calling .ToString() on an object gives you different results based on the object type. The default behavior is to print out the type of the object. But types can override this behavior. For example, calling .ToString() on a string just gives you the string itself. Calling .ToString() on an object that represents some XML might give you the XML as a string. Since List<string> doesn't override the default behavior of System.Object.ToString(), it just prints out "System.Collections.Generic.List`1[System.String]"
First, check if Session["yoursession_var"] is null. Then cast to List(). Then use Exists(), as described here: how to use Exist in List<string> in C#
i am getting error "Object reference not set to an instance of an object." my is here,
public class UserProfession
{
public UserProfession()
{
}
public System.String[] Designation
{
get;
set;
}
}
then i am using it like,
UserProfession.Designation[0] =txt_Search.Text.ToString();
Error i mentioned you hopes for your suggestions .
-Thanks
When you make an assignment to an array property, like this:
UserProfession.Designation[0] =txt_Search.Text.ToString();
what you are actually doing is calling the get section for that property... not the set. This returns the object supported the property... the whole object, and not just the index. Index lookup does not happen until after the object is returned. Once you have that object, accessing an index works in the normal way.
You get this specific exception because you have the expression UserProfession.Designation that should return a reference to an array object, but because you never initialize the array there is nothing there when you then try to find reference the 0th element. At this point the framework discovers that the array (your "object reference") is "not set to an instance of an object"... which is just a fancy way of saying it's null.
In other words, you need to have an already existing array to hold the value you want to assign. That means doing something like this:
Designation = new String[10];
public String[] Designation
{
get;
set;
}
However, notice that we never used the set section? So you can simplify that further, like this:
Designation = new String[10];
public String[] Designation {get;private set;}
This will keep client code from completely swapping an entire array out from under your object, but otherwise will provide the full functionality of an array property. If you provide your own backing store for the array, you could even get rid of the setter entirely with no loss of functionality:
private string[] _designation = new string[10];
public string[] Designation {get {return _designation;} }
But let's add one more wrinkle: your desire to assign the to array before initializing it indicates to me that you likely don't really know how big it will be up front. If that's the case, you probably want a collection of some kind instead of an array. A generic List is a convenient and very compatible replacement for an array. That would look like this:
private List<string> _designation = new List<string>();
public List<string> Designation {get {return _designation;}}
You can still access items in that list by index, just like you would with an array. The only difference you need to worry about right now is how you add new items:
UserProfession.Designation.Add(txt_Search.Text);
Also notice that I removed the .ToString() call. Since your .Text property is almost certainly already a string, calling the .ToString() method is just silly.
You will have to initialize the object, before assigning the value. The initialization should be done just once. I have initialized the array size to ten. You can have your own values here. If you want to resize dynamically, you can use ArrayList
int length = 10;
UserProfession.Designation = new System.String[length];
UserProfession.Designation[0] =txt_Search.Text.ToString();
For more information: http://msdn.microsoft.com/en-us/library/aa287601(v=vs.71).aspx
it must initialize the value before we use because, currently, it is null.
you better add the initialization code in the constructor function.
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.
I have a "format" method that works in a similar manner to the C# String.Format method, with the following signature:
In a class named StringTools:
/**
* Formats a string, based on C# String.Format method.
* #param raw A string with numbered tokens, such as "{0}, {1}"
* #param rest Values that replace the numbered tokens in raw.
*/
public static function format(raw:String, ...rest:*):String;
StringTools.format("{0}, {1}", "Hello", "World") returns the string "Hello, World" as expected. Now, I'm trying to get my logging class to use this method, but I'm having trouble passing the optional variables through. The signature of the method in the logging class is:
public static function infof(raw:String, ...rest:*):String;
If I pass "rest" directly into StringTools.format(raw, rest), it's passed in as an array, and not as a series of parameters, so if I call it liks this: infof("{0}, {1}", "Hello", "World"), I get the string "Hello,World, {1}", since it replaces the first token with the entire array of values.
I also tried constructing an arguments array, and calling the method like this:
var collectArgs:Array = [raw];
for (var i:Number = 0; i < rest.length; i++)
{
collectArgs.push(rest[i]);
}
var callFunction:Function = StringTools.format.call;
trace(callFunction.apply(null, collectArgs));
However, this traces "World,6". So, it looks like the parameters are shifted. So, I tried initializing collectArgs as [null, raw], and I get "Hello World,6. The number is {1}" again.
Am I doing something wrong? What is the correct way to pass optional parameters from one method that expects optional parameters to another method that expects optional parameters?
Thanks!
I think you are on the right lines using apply. This seems to do illustrate the behaviour you want:
static function f1(raw:String, ...rest:*):void
{
trace("f1: "+raw+" "+rest);
rest.unshift(raw);
f2.apply(null, rest);
}
static function f2(raw:String, ...rest:*):void
{
trace("f2: "+raw+" "+rest);
}
function passSomeArguments():void
{
f1("A",1,2,3);
}
EDIT: You need to pass 'null' as the 1st parameter to apply because the first parameter is what is considered to be 'this' when the function is called. Since the functions are static (and in any case have no dependency on 'this') you can pass null, but you must pass something.
You could also do something like this (of course this is not best implementation for the string formatting):
public static function format(raw:String, ...rest:*):String {
if (rest[0] is Array && rest.length == 1) {
rest = rest[0];
}
var r:RegExp = /(\{\d+\})/g;
var matches:Array = raw.match(r);
for (var i:Number = 0; i < rest.length; i++) {
raw = raw.replace(matches[i], rest[i]);
}
return raw;
}
Then your infof function would just look like this:
public static function infof(raw:String, ...rest:*):void {
var formatted = StringTools.format(raw, rest);
}
As mentioned in my comment, if you remove the call method from the end of you callFunction setter, then you do not need to supply null as the first argument. See http://livedocs.adobe.com/ to understand what the call method actually does, and what the first parameter is for.
As #stephen mentioned, it is a lot simpler to unshift your raw var onto the rest array, rather than building up a new one.
Actually, just found that it's my problem. It should work fine using the argument collection method described, as long as the first element in the arguments array is null. I'm not sure why null is necessary, but it works fine this way.
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?