Pass a set function as an argument - apache-flex

How can I pass a 'set' function as the Function Object argument of another function?
eg:
public class IdModel
{
private var _id:String;
public function IdModel(source:Source)
{
//Create Binding
BindingUtils.bindSetter(id,source,"id");
}
public function get id():String
{
return _id;
}
public function set id(value:String):void
{
_id = value;
}
}
}
In the example above the 'id' argument is being evaluated and returning a String, so it won't compile with the error: "String is not assignable to argument of type Function".
Thanks

In this particular case you don't need to; you can use BindingUtils.bindProperty instead:
BindingUtils.bindProperty(this, "id", source, "id");
But if you really want to use bindSetter and a function you can probably do:
BindingUtils.bindSetter(function (arg:*): void { id = arg; }, source, "id");

Related

Using find method of org.apache.commons.collections4.CollectionUtils with Predicate

I was using org.apache.commons.collections.CollectionUtils and for this version using find method was like this:
BeanPropertyValueEqualsPredicate objIdEqualsPredicate = new BeanPropertyValueEqualsPredicate("objId", objId);
myObj = (MyClass) CollectionUtils.find(myObjSet, objIdEqualsPredicate);
But with org.apache.commons.collections4.CollectionUtils, I don't know how to make it work.
Here what I do now but if there is a clear way of it, I will be glad to learn:
Predicate<MyClass> objIdEqualsPredicate = new Predicate<MyClass>() {
#Override
public boolean evaluate(MyClass obj) {
return obj.getObjId().equals(objId);
}
};
myObj = CollectionUtils.find(myObjSet, objIdEqualsPredicate);
Is there a way to filter some objects according to the their fields' values. If possible I don't want to use anonymous class for this.
Thanks.
As the common-beanutils still have commons-collections as dependency, you must implement the Predicate interface.
For example you can take the source code of BeanPropertyValueEqualsPredicate and refactor it, so your version implements the org.apache.commons.collections4.Predicate interface.
Or you write your own version. I would prefer not to use anonymous inner classes, because of the possibility to write unit tests for the predicate and reuse it.
Quick Example (not nullsafe,..)
#Test
public class CollectionsTest {
#Test
void test() {
Collection<Bean> col = new ArrayList<>();
col.add(new Bean("Foo"));
col.add(new Bean("Bar"));
Predicate<Bean> p = new FooPredicate("Bar");
Bean find = CollectionUtils.find(col, p);
Assert.assertNotNull(find);
Assert.assertEquals(find.getFoo(), "Bar");
}
private static final class FooPredicate implements Predicate<CollectionsTest.Bean> {
private String fieldValue;
public FooPredicate(final String fieldValue) {
super();
this.fieldValue = fieldValue;
}
#Override
public boolean evaluate(final Bean object) {
// return true for a match - false otherwise
return object.getFoo().equals(fieldValue);
}
}
public static class Bean {
private final String foo;
Bean(final String foo) {
super();
this.foo = foo;
}
public String getFoo() {
return foo;
}
}
}

How to pass a parameter to a onTimer function in flex?

I want to pass a parameter to the timer's timerEvent function.
Is it possible?
I know that in c++,I can use the function object,or just use the boost::bind.
Is there something like boost::bind?
you can also extend Timer class with your custom class, for example:
public class DataTimer extends Timer
{
private var _data:Object;
public function DataTimer(delay:Number, repeatCount:int=0)
{
super(delay, repeatCount);
_data = {};
}
public function get data():Object
{
return _data;
}
public function set data(value:Object):void
{
_data = value;
}
}
and use it in your callback function
var timerObj:DataTimer = event.currentTarget as DataTimer;
trace("data: "+timerObj.data);

Finding out where TypeErrors are thrown

I am having a problem that is driving me nuts.
Recently I configured my BlazeDS to use Array instead of ArrayCollection for performance reasons. Additionally I adjusted my templates to generate Array properties.
Everything wen't fine. All except one function that causes TypeError: Error #1034. These are being thrown before the result callback is called. It claims to have problems casting an ArrayCollection to Array. I removed the generated types to make Flex use Objects instead, but these did not contain any ArrayCollections. My question now is: How can I get the stack-traces of errors thrown in event-handlers?
I allready added handlers for unhandledExceptions in all of my modules and they are called if errors occur in code triggered from user-interaction, but they don't seem to be able to catch stuff thrown by event-handlers.
How can I track these Errors?
Chris
PS: The classes are:
package de.upw.ps.ucg.model.ucg.scheduler {
[Bindable]
[RemoteClass(alias="de.upw.ps.ucg.model.ucg.scheduler.Task")]
public class Task extends TaskBase {
}
}
And:
package de.upw.ps.ucg.model.ucg.scheduler {
import de.upw.ps.ucg.model.oval.common.OvalVersionedIdentifier;
import flash.utils.IExternalizable;
[Bindable]
public class TaskBase {
public function TaskBase() {}
private var _aborted:Boolean;
private var _characteristicsId:String;
private var _currentExecutorPhase:JobExecutorPhase;
private var _definitionSetName:String;
private var _definitionSetVid:OvalVersionedIdentifier;
private var _endTime:Date;
private var _enqueueTime:Date;
private var _environmentId:String;
private var _environmentName:String;
private var _messages:Array;
private var _numberOfDefinitions:int;
private var _processedNumberOfTests:int;
private var _resultsId:String;
private var _schedulerJob:SchedulerJob;
private var _startTime:Date;
private var _statusMessage:String;
private var _taskId:String;
private var _totalNumberOfTests:int;
public function set aborted(value:Boolean):void {
_aborted = value;
}
public function get aborted():Boolean {
return _aborted;
}
public function set characteristicsId(value:String):void {
_characteristicsId = value;
}
public function get characteristicsId():String {
return _characteristicsId;
}
public function set currentExecutorPhase(value:JobExecutorPhase):void {
_currentExecutorPhase = value;
}
public function get currentExecutorPhase():JobExecutorPhase {
return _currentExecutorPhase;
}
public function set definitionSetName(value:String):void {
_definitionSetName = value;
}
public function get definitionSetName():String {
return _definitionSetName;
}
public function set definitionSetVid(value:OvalVersionedIdentifier):void {
_definitionSetVid = value;
}
public function get definitionSetVid():OvalVersionedIdentifier {
return _definitionSetVid;
}
public function set endTime(value:Date):void {
_endTime = value;
}
public function get endTime():Date {
return _endTime;
}
public function set enqueueTime(value:Date):void {
_enqueueTime = value;
}
public function get enqueueTime():Date {
return _enqueueTime;
}
public function set environmentId(value:String):void {
_environmentId = value;
}
public function get environmentId():String {
return _environmentId;
}
public function set environmentName(value:String):void {
_environmentName = value;
}
public function get environmentName():String {
return _environmentName;
}
public function set messages(value:Array):void {
_messages = value;
}
public function get messages():Array {
return _messages;
}
public function set numberOfDefinitions(value:int):void {
_numberOfDefinitions = value;
}
public function get numberOfDefinitions():int {
return _numberOfDefinitions;
}
public function set processedNumberOfTests(value:int):void {
_processedNumberOfTests = value;
}
public function get processedNumberOfTests():int {
return _processedNumberOfTests;
}
public function set resultsId(value:String):void {
_resultsId = value;
}
public function get resultsId():String {
return _resultsId;
}
public function set schedulerJob(value:SchedulerJob):void {
_schedulerJob = value;
}
public function get schedulerJob():SchedulerJob {
return _schedulerJob;
}
public function set startTime(value:Date):void {
_startTime = value;
}
public function get startTime():Date {
return _startTime;
}
public function set statusMessage(value:String):void {
_statusMessage = value;
}
public function get statusMessage():String {
return _statusMessage;
}
public function set taskId(value:String):void {
_taskId = value;
}
public function get taskId():String {
return _taskId;
}
public function set totalNumberOfTests(value:int):void {
_totalNumberOfTests = value;
}
public function get totalNumberOfTests():int {
return _totalNumberOfTests;
}
}
}
Both classes are generated by my maven build from a corresponding Java Class and the Types do fit together nicely.
Do you have access to the socket class that's reading in all these messages? Trace out the buffer before the deserialisation and you should at least be able to find the class that's giving you hassle.
Failing that, trace out the object after deserialisation and it should be the very first one after the error is thrown.
This is something you'll have to debug on your own, but I have a gut feeling that the problem is because the data being sent by your java DTO is not the same as your AS3 class, even though that you have the RemoteClass metadata saying that it is.
Are you missing a property? or have a property mismatch? That is the most likely cause of your error. I suggest you debug the java side as much as you can and use something like firebug to see the request/response of the server.

Flex DropdownList does not show the correct values

I have a Flex Spark dropdownList in which I need to show the Provider FirstName,LastName:
<s:DropDownList id="providerList"
dataProvider="{model.practiceProviderList.practiceProviders}"
labelField="provider.providerName.firstName"/>
But the output shows only [object Object] & [object Object] as there are 2 providers in the DB and does not show the actual values.
The PracticeProviderList.as:
[Bindable]
[RemoteClass(alias="model.PracticeProviderList")]
public class PracticeProviderList extends PracticeProviderListBase {
private var _practiceProviderList:ArrayCollection;
public function get practiceProviders():ArrayCollection
{
return _practiceProviderList;
}
public function set practiceProviders(value:ArrayCollection):void
{
_practiceProviderList = value;
}
The PracticeProvider Object:
public class PracticeProvider {
private var _practiceId:Number;
private var _practiceProviderId:Number;
private var _provider:Provider;
public function set practiceId(value:Number):void {
_practiceId = value;
}
public function get practiceId():Number {
return _practiceId;
}
public function set practiceProviderId(value:Number):void {
_practiceProviderId = value;
}
public function get practiceProviderId():Number {
return _practiceProviderId;
}
public function set provider(value:Provider):void {
_provider = value;
}
public function get provider():Provider {
return _provider;
}
The Provider has providerName:PersonName as one of it's fields & PersonName has firstName:String & lastName:String
I need to show the First Name, Last Name in the dropdownlist. I would appreciate if someone can help in this regard.
Thanks
Harish
The labelField can't concatenate 2 values. Use a labelFunction instead.
If I understand your data model, Something like this:
public function myLabelFunction(item:Object):String{
return item['providerName']['PersonName']['firstName'] + ' ' + item['providerName']['PersonName']['lastName']
}

how to use the Function type in AS3 (var f:Function) for a method f(s:String)

i have a class that has something like this
public class Foo {
public var f:Function;
public void method(s:String)
{
f.invoke(s);
}
}
so i need to assign to the f a function that takes an argument f(s), something like
myFoo.f = thefunction
function(s:String)
how to do all this, so it will work correctly ?
Just to add a nice example:
import mx.events.FlexEvent;
public var f:Function;
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
f = addSmile;
method(' my string');
f = addFrown;
method(' my string');
// Or you can do it straight like this:
f(' my string');
// Or alternatively write a function for replacing f
makeF(addSmile);
f(' my string');
}
public function method(s:String):void
{
f(s);
}
private function addSmile(s:String):void
{
trace (s+' :)');
}
private function addFrown(s:String):void
{
trace (s+' :(');
}
protected function makeF(newF:Function):void
{
f= newF;
}
will output
my string :)
my string :(
my string :(
my string :)
if you are meaning, how to do anonymous functions...
myFoo.f = function( s : String ) {
//do Stuff to string
}
Then you can use the code you have above.
You should not point anywhere, that your function takes one String argument. If it takes int, or takes 2 arguments, - it would be a runtime error.
myFoo.f = myFunction;
public void function myFunction(s: String): void
{
}
public class Foo {
public var f:Function;
public void method(s:String)
{
f(s);
}
}

Resources