flex/actionscript assignment failing? - apache-flex

I'm seeing something weird in my actionscript code
I have two classes foo and bar, bar extends foo. In a model class I have a foo member variable, I assign an bar object to the foo variable. But after the assignment the foo variable is null.
[Bindable] public var f:foo;
public function someFunc(arr:ArrayCollection):void {
if(arr.length > 0) {
var tempBar:bar = arr.getItemAt(0) as bar;
if(tempBar != null) {
tempBar.someProp++;
f = tempBar;
// f is now null
}
}
}
Any ideas on what I could be doing wrong?
EDIT
Here is the exact code:
[Bindable] public var selectedCustomerJob:IDSCustomer;
public function selectedJobByIdCallback(evt:Event):void
{
var temp:IDSDTOArrayCollection = evt.currentTarget as IDSDTOArrayCollection;
if(null != temp && temp.length > 0)
{
selectedCustomerJob = IDSJob(temp.getItemAt(0));;
trace(" selectedCustomerJob: " + flash.utils.getQualifiedClassName(selectedCustomerJob));
trace(" jobToSelect type: " + flash.utils.getQualifiedClassName(temp.getItemAt(0)));
trace("jobToSelect super class: " + flash.utils.getQualifiedSuperclassName(temp.getItemAt(0)));
}
}
this is the trace output:
selectedCustomerJob: null
jobToSelect type: com.intuit.sb.cdm.v2::IDSJob
jobToSelect super class: com.intuit.sb.cdm.v2::IDSCustomer

Casting using the as keyword returns null when it fails. In this case, the first item in the array collection may not be an object of type Bar as you expect; it could be a Foo or something else. You can cast subclass object to base-class but not the other way.
Use the parenthesis syntax for casting - it'll throw an exception if cast fails and thus you can figure out the type of arr.getItemAt(0).
//Change
var tempBar:Bar = arr.getItemAt(0) as Bar;
//to
var tempBar:Bar = Bar(arr.getItemAt(0));
to make sure that the first item in the array collection is indeed a Bar instance (and not Foo or something else).
Otherwise you can find the type using
trace(flash.utils.getQualifiedClassName(arr.getItemAt(0)));
if(tempBar != null) {
tempBar.someProp++;
f = tempBar;
// f is now null
}
By the way, I believe the posted code is not the exact code you ran because for f to be null, tempBar should be null as you assigning it to f. In that case the code inside if should not be executed as you're checking for null inside if. Even if it enters the if block, it will throw a null pointer error (#1009) in the first line where you're trying to increment tempBar.someProp

Related

Getting member variables through reflection in Kotlin

If I have a class in Kotlin:
class Foo{
var x= null
var y=null
}
I want to check which of these members have been set at runtime through reflection. I can iterate over them and check for null in Java.
Foo foo= new Foo();
//this gives me the value of foo.x
Foo.class.getDeclaredField("x").get(foo);
How can I do the same in Kotlin/Native? I know I can achieve this in Android by
Foo::class.java.getDeclaredField("x").get(foo)
But this doesn't work in native environment.
I'm just going by the documentation, so the below may be a bit wrong, but you could try this:
val prop : KCallable = Foo::class.members.firstOrNull { it.name == "x" }
if (prop != null) {
val xValue : Int? = prop.call(object)
//you have to declare the type of the xValue
}

Meaning of interrogation

I'm a little bit confuse about the meaning difference of using "?"
I offen saw this:
var foo?: number = "bar"
But also saw this:
function foo(bar: {baz: ?string}) { ... }
And also saw both together.
I've read about invariants and maybe types, but if I understood it right, both signals have the same meaning, which is: "this type is of kind 'X', but it maybe is null or undefined".
Is it right or am I getting it wrong?
Here are answers to most of your questions:
// Don't know what this is, or why you would use it
// Error: undefined is incompatible with string
var foo1?: string = undefined;
// ?string means string, null, or undefined
var foo2: ?string = undefined;
type FooOptional = { foo?: string };
type FooMaybe = { foo: ?string };
// If it's optional it can be completely omitted
var foo3: FooOptional = {};
// It can also be explicitly set to undefined
var foo4: FooOptional = { foo: undefined };
// But not null!
var foo5: FooOptional = { foo: null };
// If it's a maybe type, it must be specified
// Error: property `foo` not found
var foo6: FooMaybe = {};
// But you can set it explicitly to null or undefined
var foo7: FooMaybe = { foo: null };
var foo8: FooMaybe = { foo: undefined };
(tryflow link)
Using both together (e.g. {foo?: ?string} as a type) usually (but not in all cases) indicates that the author doesn't quite know what type they want to use and have just added question marks until it typechecks. Typically I have found that if I think it through, it makes sense to use either an optional property or a maybe type, but not both.

unable to evaluate viewState against Null

This method I am using to fill the data source for a grid view, but for when getnew is false, it won't return any value , just returns a list with a single null value in it.
private List<T> GetAll_T(bool getNew)
{
if (getNew)
return (ViewState["T"] = Get_T()) as List<T>;
//Get_T() returns a CustomList
return new List<T>
{
ViewState["T"] != null ?
ViewState["T"] as T:
(T)(ViewState["T"] = Get_T()) Collection
};
}
it gives me a warning for second line[when view state is null].expression is always false
why there is warning, when it's logically correct !
It is not clear from your code snippet what CustomerService.GetAllCustomer() returns.
You use it both like it returns a list on line(2) of the function and like it returns a single object on line(8).
I suggest writing it like this
private List<CustomerMaster> GetAllCustomer(bool getNew)
{
if (getNew || null == ViewState["CustomerDataset"])
ViewState["CustomerDataset"] = CustomerService.GetAllCustomer();
return ViewState["CustomerDataset"] as List<CustomerMaster>;
}

Flex looping through object

Im trying to extend the flex ArrayCollection to be able to search for an object containing specific data and give it back.
Here is my function:
public function getItemContaining(value: String): Object {
//Loop through the collection
for each(var i: Object in this) {
//Loop through fields
for(var j: String in i) {
//If field value is equal to input value
if(i[j] == value) {
return i;
}
}
}
//If not found
return null;
}
Problem is j is always null so the second loop never works. So I read flex loop descriptions and actually it should work just fine. What can possibly be the problem?
Try it like this:
for (var name:String in myObject){
trace(name + ":" + myObject[name];
}
Okay that was actually the same you were doing. The error must be in this line:
for each(var i: Object in this) {
Try using this:
for each(var i: Object in this.source) {
My first instinct would be to have a look at data type. You're setting up a loop declaring j:String and the symptom is that j is always null. This suggests to me that Flex is failing to interpret the elements of i as strings. If Flex only recognizes the elements of i as Objects (because all Strings are Objects, and Objects are the lowest common denominator), it would return null for j:String.
Try this for your inner loop:
for(var j: Object in i) {
//If field value is equal to input value
if(i[j] is String && (i[j] as String) == value) {
return i;
}
}
if you are using ArrayCollection as your datasource, you should look at using the IViewCursor interface. You can supply a custom compare function, or supply the fields top compare to. This interface is well documented with examples in adobe/livedocs
var _cursor:IViewCursor;
var _idSortField:SortField;
var _idSort:Sort = new Sort();
_idSortField = new SortField();
_idSortField.compareFunction = this.myCompareFunction;
_idSort.fields = [_idSortField];
myArrayCollection.sort = _idSort;
myArrayCollection.refresh();
_cursor = myArrayCollection.createCursor();
if (_cursor.findAny(search))
return _cursor;
if you are search for a value in a specific property, then its even easier. Here's the link to adobe livedocs on this topic

Does An Object Have "Children"

I just want to know if the object in question, has any sub-objects within it or not.
Do I really have to do THIS:
public static function getLength(o:Object):bool
{
for (var item:* in o)
if (item != "mx_internal_uid")
return true;
return false;
}
Isn't there some way to say SOMETHING LIKE: Object.hasChildren();
OR EVEN Object.childCount();
The Object in question does NOT extend the DisplayObjectContainer. It is just something like:
var Ob:Object;
Ob.SomeProp="xxx";
Ob.SomeOtherProp="zzz";
How can I know how many "entries" there are in the object. (in this case 2).
In other words, how does "for (var item:* in Ob)" know when to stop.
???
A good class to inspect objects is the flex built in ObjectUtil. I think what you're trying to achieve would be done by using (obj is the object to analyze):
ObjectUtil.getClassInfo(obj).properties.length
But ObjectUtil.getClassInfo would be a good place too look if you're trying to analyze an object, it returns a lot of information (read more on LiveDocs).
It also has a function to check if a variable is a simple one - ObjectUtil.isSimple
By object you mean the Object class, hence counting the properties, or the object on the displaylist, if the latter, that objects surely extends DisplayObjectContainer wich has the numChildren property
As kajyr says, if it's a DisplayObjectContainer you can check for numChildren.
If you want to check if a generic objects contains simple properties ( primitives like Number,int, uint, String, Boolean ) or complex properties (subObjects, instances of some class ) that you might regards as children to that generic object, you do the following:
var testObj:Object = {id:1,name:'DumDum'};
var testObj2:Object = {id:2,name:'NumNum',data:[1,2,3,4,5,6,7,8,9],somethingComplex:{firstName:'Num',lastName:'Num'}};
trace(isSimple(testObj).length == 0);//prints true
trace(isSimple(testObj2).length == 0);//prints false
trace(isSimple(testObj2));
function isSimple(obj:*):Array{
var complex:Array = [];
for(var prop in obj){
if(!(obj[prop] is String || obj[prop] is int || obj[prop] is uint || obj[prop] is Number || obj[prop] is Boolean))
complex.push({prop: obj[prop]});
}
return complex;
}
If you want to get the number of members (variables associated with an object), that is easy enough to get:
var Ob:Object = {};
Ob.SomeProp="xxx";
Ob.SomeOtherProp="zzz";
trace(getMembersNum(Ob));//prints 2
function getMembersNum(obj:*):int{
var result:int = 0;
for(var prop in obj) result++;
return result;
}
You would write this in your utility package/class maybe like this:
public static function get numMembers(obj:*):int{
var result:int = 0;
for(var prop in obj) result++;
return result;
}
HTH

Resources