[flexcoders] Re: Reusing HTTPService
Yeah, that's a great idea. Kind of like the Command pattern with handlers, right? LT --- In flexcoders@yahoogroups.com, Dmitri Girski [EMAIL PROTECTED] wrote: No worries. BTW, there is another way of doing it - each request is represented by some object which creates HTTPService and subscribes for the response. Because each instance sends single request, there is no problem to decode the response. Cheers, Dmitri. --- In flexcoders@yahoogroups.com, lagos_tout lagos.tout@ wrote: Thanks, Dmitri. This is a great idea. Unfortunately though, in this project, I don't have control over what's returned by the server, so I can't add the requestId. But with your suggestion, you still end up needing to match requestIds with handlers on the client right? So do you use a massive switch for that? Thanks again. LT --- In flexcoders@yahoogroups.com, Dmitri Girski mitek17@ wrote: If I were you, I would simply add the requestId into the server's response, so client always knows which request-response pair it handles. This idea lies behind most of the transmissions protocols. Cheers, Dmitri. --- 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
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
[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.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.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
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
[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, 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:[EMAIL PROTECTED] On Behalf Of lagos_tout Sent: Friday, October 10, 2008 8:35 PM To: flexcoders@yahoogroups.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
[flexcoders] Re: Reusing HTTPService
Thanks, Dmitri. This is a great idea. Unfortunately though, in this project, I don't have control over what's returned by the server, so I can't add the requestId. But with your suggestion, you still end up needing to match requestIds with handlers on the client right? So do you use a massive switch for that? Thanks again. LT --- In flexcoders@yahoogroups.com, Dmitri Girski [EMAIL PROTECTED] wrote: If I were you, I would simply add the requestId into the server's response, so client always knows which request-response pair it handles. This idea lies behind most of the transmissions protocols. Cheers, Dmitri. --- 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
[flexcoders] Re: Reusing HTTPService
No worries. BTW, there is another way of doing it - each request is represented by some object which creates HTTPService and subscribes for the response. Because each instance sends single request, there is no problem to decode the response. Cheers, Dmitri. --- In flexcoders@yahoogroups.com, lagos_tout [EMAIL PROTECTED] wrote: Thanks, Dmitri. This is a great idea. Unfortunately though, in this project, I don't have control over what's returned by the server, so I can't add the requestId. But with your suggestion, you still end up needing to match requestIds with handlers on the client right? So do you use a massive switch for that? Thanks again. LT --- In flexcoders@yahoogroups.com, Dmitri Girski mitek17@ wrote: If I were you, I would simply add the requestId into the server's response, so client always knows which request-response pair it handles. This idea lies behind most of the transmissions protocols. Cheers, Dmitri. --- 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
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
[flexcoders] Re: Reusing HTTPService
If I were you, I would simply add the requestId into the server's response, so client always knows which request-response pair it handles. This idea lies behind most of the transmissions protocols. Cheers, Dmitri. --- In flexcoders@yahoogroups.com, lagos_tout [EMAIL PROTECTED] 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