Re: [flexcoders] Re: Reusing HTTPService

2008-10-17 Thread shaun

How about something like this:

(note: I've not tried it, just slapped it straight into the email)

public class MyClassThatInvokesHTTPServices {

//inner helper class.
class MyIResponder implements IResponder{
   public var f:Function;
   public var r:Function;

   public MyIResponder(r:Function, f:Function){
 this.r = r;
 this.f = f;
   }

   public function fault(info:Object):void {
   f.call(info);
   }

   public function result(result:Object):void {
   r.call(result);
   }
}

//Your handlers for service calls.
protected function resultA(result:Object){ ... }
protected function faultA(info:Object){...}
protected function resultB(result:Object){ ... }
protected function faultB(info:Object){...}

var service:HTTPService ...//assume exists, reused for various calls.

  //send for service A.
  funciton sendA(args:Object){
service.url = ../A.html;
service.send(args).addResponder(new MyIResponder(resultA, faultA));
  }

  //send for service B.
  function sendB(){
service.url = ../B.html;
service.send().addResponder(new MyIResponder(resultB, faultB));
  }


}

[snip]

 --- In flexcoders@yahoogroups.com, lagos_tout lagos.tout@ 
 wrote:
 Hi,

 I'm re-using an instance of HTTPService, changing the request 
 arguments to get different responses from the server.  But I 
 found 
 that if, for instance, I made 3 calls this way with the 
 HTTPService, 
 each of the 3 result handlers registered for each call is 
 executed 
 every time a result returned.  

 I solved this by storing a reference to the unique AsyncToken 
 returned 
 by each service call and matching it to the AsyncToken 
 contained 
 in 
 each ResultEvent's token property in order to determine 
 which 
 result 
 handler to execute. 

 I'm not terribly happy with this setup.  It seems messy.  I'd 
 appreciate any suggestions on how I can reuse an HTTPService 
 instance 
 without ending up with long switch statements with countless 
 if 
 thisAsyncToken then do thisHandler, else if thatAsyncToken 
 then 
 do 
 thatHandler... and so on.

 Thanks much.

 LT

 
 
 
 



RE: [flexcoders] Re: Reusing HTTPService

2008-10-17 Thread Jeff Vroom
I do like this approach - that's what I do when I code using AsyncTokens.

In the SDK's trunk depot, we have implemented a different way of using the 
AsyncTokens which makes it easier to add per-call event listeners and result 
objects particularly from MXML.   It is in the class mx.rpc.CallResponder.  
Here's a sample of how you'd use it:

mx:CallResponder id=myResponder result=optionalEventHandler(event) 
fault=optionalFaultHandler(event)/
mx:Button click=myResponder.token = myService.getAllEmployees()/
mx:DataGrid dataProvider={myResponder.lastResult}/

Each CallResponder monitors a single AsyncToken at a time and propagates its 
result and fault events to listeners on the call responder.  It also stores the 
lastResult property.  This allows you to cache the previous result while the 
next call is in progress.   Any feedback folks have on this approach will be 
appreciated.

I'll admit that modifying the token after the call was made is 
counter-intuitive.  It works because the AS VM cannot deliver any events on 
that token until after the current executing code path has completed.   We did 
consider passing in the token as an argument to the async calls but didn't 
think it really made things easier to understand and adds a risk that you'll 
use the same token for two simultaneous calls.

Jeff



From: flexcoders@yahoogroups.com [mailto:[EMAIL PROTECTED] On Behalf Of 
lagos_tout
Sent: Friday, October 17, 2008 10:33 AM
To: flexcoders@yahoogroups.com
Subject: [flexcoders] Re: Reusing HTTPService


I like! This line says it all:

 service.send().addResponder(new MyIResponder(resultB, faultB));

Thanks much. I think this is the solution.

It meets my requirements: no long conditionals; one-to-one matching of
service calls to fault/result handlers; reuse of the same service
object; and, if i create a separate class (implemementing IResponder
and containing it's own fault and result handlers, rather than passing
it in as you've done) for each type of service call, i think i get to
live another day by the OO mantra closed to modification, open to
extension.

Weird though how Flex requires one to add the responder after the call
is already made, don't you think? One would think the responder
should be in place before the call to service.send().

Thanks again!

LT

--- In flexcoders@yahoogroups.commailto:flexcoders%40yahoogroups.com, shaun 
[EMAIL PROTECTED] wrote:


 How about something like this:

 (note: I've not tried it, just slapped it straight into the email)

 public class MyClassThatInvokesHTTPServices {

 //inner helper class.
 class MyIResponder implements IResponder{
 public var f:Function;
 public var r:Function;

 public MyIResponder(r:Function, f:Function){
 this.r = r;
 this.f = f;
 }

 public function fault(info:Object):void {
 f.call(info);
 }

 public function result(result:Object):void {
 r.call(result);
 }
 }

 //Your handlers for service calls.
 protected function resultA(result:Object){ ... }
 protected function faultA(info:Object){...}
 protected function resultB(result:Object){ ... }
 protected function faultB(info:Object){...}

 var service:HTTPService ...//assume exists, reused for various
calls.

 //send for service A.
 funciton sendA(args:Object){
 service.url = ../A.html;
 service.send(args).addResponder(new MyIResponder(resultA,
faultA));
 }

 //send for service B.
 function sendB(){
 service.url = ../B.html;
 service.send().addResponder(new MyIResponder(resultB, faultB));
 }


 }

 [snip]

  --- In flexcoders@yahoogroups.commailto:flexcoders%40yahoogroups.com, 
  lagos_tout lagos.tout@
  wrote:
  Hi,
 
  I'm re-using an instance of HTTPService, changing the request
  arguments to get different responses from the server. But I
  found
  that if, for instance, I made 3 calls this way with the
  HTTPService,
  each of the 3 result handlers registered for each call is
  executed
  every time a result returned.
 
  I solved this by storing a reference to the unique AsyncToken
  returned
  by each service call and matching it to the AsyncToken
  contained
  in
  each ResultEvent's token property in order to determine
  which
  result
  handler to execute.
 
  I'm not terribly happy with this setup. It seems messy. I'd
  appreciate any suggestions on how I can reuse an HTTPService
  instance
  without ending up with long switch statements with countless
  if
  thisAsyncToken then do thisHandler, else if thatAsyncToken
  then
  do
  thatHandler... and so on.
 
  Thanks much.
 
  LT
 
 
 
 
 


inline: image001.jpginline: image002.jpg

RE: [flexcoders] Re: Reusing HTTPService

2008-10-16 Thread Tracy Spratt
Yes, AsyncToken is dynamic.  Example:

Invoke send:

var oRequest:Object = new Object();

oRequest.Arg1 = value1;

var callToken:AsyncToken = service.send(oRequest);

callToken.callId = myQuery1; 

 

In the result Handler:

  var callToken:AsyncToken = event.token;

  var sCallId = callToken.callId;  //myQuery1

  switch(sCallId)  {//Process the
result conditionally

case myQuery1:

  //do whatever. this example calls another data service query

  break;

...

 

Tracy



From: flexcoders@yahoogroups.com [mailto:[EMAIL PROTECTED] On
Behalf Of lagos_tout
Sent: Thursday, October 16, 2008 2:26 AM
To: flexcoders@yahoogroups.com
Subject: [flexcoders] Re: Reusing HTTPService

 

Hi, Tracy.

Thanks for your response.
It's good to hear that others use this solution. Makes me feel like 
it's not just a stop-gap hack.
However, what made me uncomfortable is the idea in OOP that classes 
should be open to extension, closed to modification. It's generally a
code smell if one keeps having to literally add code to an existing 
class in order to add functionality. Especially when the added 
functionality bears such a strong resemblance to existing behaviors.
What do you think?
I really like your idea of adding properties to AsyncToken. Is 
AsyncToken a dynamic class? Is that how you do it?
Thanks again.

LT

--- In flexcoders@yahoogroups.com mailto:flexcoders%40yahoogroups.com
, Tracy Spratt [EMAIL PROTECTED] wrote:

 This is a normal pattern. What about it makes you uncomfortable? 
You
 are using a single result handler function, correct? The switch()
 statement makes chaining calls easy and facilitates debugging since 
a
 single breakpoint or trace() will track all RPC calls. I have found
 that two string properties (callId, and nextAction ) on the
 AsyncToken work for all my needs so far
 
 
 
 An alternative would be to put a callback function in an AsyncToken
 property or use the addResponder() methods. I personally find 
those
 solutions messy.
 
 
 
 Tracy
 
 
 
 
 
 From: flexcoders@yahoogroups.com mailto:flexcoders%40yahoogroups.com
[mailto:flexcoders@yahoogroups.com mailto:flexcoders%40yahoogroups.com
] 
On
 Behalf Of lagos_tout
 Sent: Friday, October 10, 2008 8:35 PM
 To: flexcoders@yahoogroups.com mailto:flexcoders%40yahoogroups.com 
 Subject: [flexcoders] Reusing HTTPService
 
 
 
 Hi,
 
 I'm re-using an instance of HTTPService, changing the request 
 arguments to get different responses from the server. But I found 
 that if, for instance, I made 3 calls this way with the HTTPService, 
 each of the 3 result handlers registered for each call is executed 
 every time a result returned. 
 
 I solved this by storing a reference to the unique AsyncToken 
returned 
 by each service call and matching it to the AsyncToken contained in 
 each ResultEvent's token property in order to determine which 
result 
 handler to execute. 
 
 I'm not terribly happy with this setup. It seems messy. I'd 
 appreciate any suggestions on how I can reuse an HTTPService 
instance 
 without ending up with long switch statements with countless if 
 thisAsyncToken then do thisHandler, else if thatAsyncToken then do 
 thatHandler... and so on.
 
 Thanks much.
 
 LT