Copyright © 2004 O'Reilly Media, Inc. All Rights Reserved.
Programming Flash Communication Server
By Brian Lesser, Giacomo Guilizzoni, Robert Reinhardt, Joey Lott, Justin Watkins
February 2005
ISBN: 0-596-00504-0
http://www.oreilly.com/catalog/progflashcs/index.html
Available from booksellers or direct from O'Reilly Media, www.oreilly.com.

Cover image
This content is excerpted from the above-named O'Reilly publication, with permission, by agreement with ActionScript.org.

You have already been introduced to two ways to handle a response to a remoting call: using a methodname_Result( ) method or using an onResult( ) method attached to a response object. Both approaches handle the results in the same manner.

To handle the results with methodname_Result( ), simply define a function using the same name as the remote method call and append "_Result" to the end:

doGoogleSearch_Result = function (data) {
trace(data);
};

This approach is the easiest to implement. If you do not pass a default responder to the getService( ) method, the response methods must be defined in the same scope as the service proxy object. However, if you specify a default responder to getService( ), the response methods must be defined as methods of that object.

To handle the results with an onResult( ) method, you must define an object with an onResult( ) method and register that object as the responder. You can either pass the object to the getService( ) method:

responder = new Object( );
responder.onResult = function (data) {
    trace(data);
};
myService = my_conn.getService("AuthenticationService", responder);

or you can pass the object as the first parameter of the remote method call:

myService.authenticateUser(responder, "jwatkins", "abcd");

If you aren't very comfortable using objects, the methodname_Result( ) approach allows you to handle results by simply defining functions with the appropriate names. If you are comfortable with object-oriented programming, you can also implement the methodname_Result( ) approach by designing a class to handle the results from the remoting calls. You can create all of the response methods in the class and pass an instance of the class as the default response object to the getService( ) method:

function ResultsClass (  ) {...}
ResultsClass.prototype.method1_Result = function ...
ResultsClass.prototype.method2_Result = function ...

myService = my_conn.getService("TestService", new ResultClass( ));

There are several drawbacks to using methodname_Result( ), however. Because the response handler's name depends on the remote function's name, you must define separate _Result handlers for each method. Furthermore, if the name of a remote function changes, you must change the name of its corresponding _Result handler.

Using an onResult( ) method instead of a _Result handler is cleaner from an object-oriented standpoint. Simply pass an object that defines an onResult( ) method. The object can be either an anonymous object or an instance of a class. This approach makes it easier to share response-handling logic across different remote calls; you can pass the same response object to several remote methods or set up one object as the default responder and override it when necessary.

The NetServices package dispatches the onResult event from a remote call in the following order, stopping when it finds an appropriate handler:

  1. First, it looks for a function named methodname_Result( ) defined on the response object or the current timeline.

  2. Otherwise, if a response object with an onResult( ) method was specified in the call to getService( ), results are sent to that onResult( ) method.

  3. Otherwise, if the first argument passed to the remote method invocation is an object that defines an onResult( ) method, results are sent to that onResult( ) method.

  4. Otherwise, if the movie is playing in the authoring environment, results are sent to the Output window.

  5. Otherwise, the results are lost.

Using the onResult( ) approach is also slightly faster. When you do not specify an object with an onResult( ) method, the NetServices classes have to create an additional object to handle the results from the server and forward the request to the methodname_Result( ) method.

Warning

A bug in the NetServices class prevents responder objects with an onResult( ) method from working as expected. This bug existed in prior versions but is fixed in the Updater 2 for FlashCom 1.5.

If you prefer to name your response handler something other than onResult( ), Example 11-3 defines a custom class that forwards the results to an object and method name of your choosing. The class defines an onResult( ) method that calls the object and method name originally passed to the RelayResponder class constructor.

Example 11-3. Using a RelayResponder

#include "NetServices.as"

NetService.setDefaultGatewayUrl("http://localhost/flashservices/gateway");

function RelayResponder (targetObject, targetMethod) {
  this.targetObject = targetObject;
  this.targetMethod = targetMethod;
}
RelayResponder.prototype.onResult = function (data) {
  this.targetObject[this.targetMethod](data);
};

function FictionalDataClass ( ) {
}

var o = FictionalDataClass.prototype;
o.getData = function ( ) {
  this.conn = NetServices.createGatewayConnection( );
  this.service = this.conn.getService("DataService");
  this.service.getData(new RelayResponder(this, "receiveData"));
};
o.receiveData = function (data) {
  trace("The request was forwarded here");
};

myData = new FictionalDataClass( );
myData.getData( );