The basic Cairngorm Event Flow that is handled in Part 3 is essential to any Cairngorm application, but most applications interact with a server. The Service to Worker pattern that was discussed in the previous tutorial is essential to this process. To learn the expanded Cairngorm Flow, you will need to learn a few new Cairngorm elements.
The Server Interaction Elements
There are three new types of classes that you will need to be familiar with to understand the full Service to Worker Pattern.
Organizing Your Cairngorm Project (With Server Interaction)
In the last tutorial you saw the standard Cairngorm structure for a project. To complete this structure, you will need to add an additional two folders:
Understanding the Process
Before you begin crafting the server interaction for your project, you need to understand the full Service to Worker pattern. Figure 1 illustrates the entire process.

Figure 1 - Cairngorm Event Flow with Server Interaction
Phase I - Execution Phase
Phase II - Application Tier Processing
Phase III - Response Phase
Note: Traditionally the Command and Responder were the same class in a Cairngorm application. If you are working with other developers, the applications will probably be coded in this manner. However, most developers (including Adobe Consulting) are now separating these classes into two different classes. For a less complex project, it might not make sense to separate these items, but in a large application it could prove advantageous in organization and practice to have two different classes.
The ServiceLocator
The ServiceLocator is a singleton that contains references to all of the services that the application will be using. These services can be RemoteObjects, HTTPServices, WebServices, or custom services. Like the FrontController, this class is usually instantiated in your main application file. Unlike many of the other Cairngorm project assets that you have created, this class can be defined in MXML (as well as ActionScript). To properly define this in MXML, there must be a namespace that points to the business folder of the Cairngorm package. In this case the namespace cairngorm is typically used. The ServiceLocator in Code Example 1 has one service defined, loginService.
Code Example 1 - Sample ServiceLocator
The ServiceLocator is typically named Services.mxml and resides in the business folder of your Cairngorm project.
Commands with Server Interaction
In the last tutorial you hard-coded some values into the LoginCommand to check for a specific username and password. Here was the execute method:
Code Example 2 - Command Without Delegate
This methodology will hold true for any Command that doesn't have server interaction, but if you do have server interaction, it will need to be modified to include the delegate. First, you will need to make a decision. As stated earlier, you can have separate Commands and Responders, or they can be the same class. For this example, they will be the same class. The Command will now also need to implement the mx.rpc.IResponder class (please note that com.adobe.cairngorm.business.Responder is deprecated and should no longer be used).
The other initial change is that the execute method now instantiates a class named LoginDelegate (which will be created shortly). The LoginDelegate class required one argument in its constructor, the Responder of the service. In this case, the Command will function both as the command and the responder, so you simply need to insert the this keyword inside the parenthesis. If you chose to have a separate responder, you would insert the reference to it here (instead of the this keyword).
Code Example 3 - Command with Server Interaction Through a Delegate
Value Objects
A Value Object does not extend or implement any Cairngorm class. As stated earlier, it simply is a class that is only required to have properties, but not methods. For example, if you created a Value Object for a Login - it would have a property for username and a property for password.
Code Example 4 - Value Object for Login
The RemoteClass metatag is important to note. This will allow the corresponding server-side object (ColdFusion Component, PHP Class, Java Class, etc...) to be mapped to this Value Object. In this case, it is mapped to a ColdFusion component named LoginVO in the CairngormTest folder.
Business Delegates
The final design pattern in the Cairngorm Micro-Architecture is the Business Delegate. A Business Delegate essentially is the abstraction layer between your services and the rest of your application. As stated earlier, it has three functions. First, the Business Delegate will locate the service that is needed in the ServiceLocator. Second, it will call a method on that service. Finally, it will route the response back to the specified responder (usually either a command or separate responder).
A Delegate class doesn't extend or implement and Cairngorm classes, but it generally follows the following guidelines.
Code Example 5 - Service Delegate
There are many benefits to having this layer. If coded correctly, you should be able to change out the server interaction (going from PHP to ColdFusion for example) and only have to change the code in your ServiceLocator and your Delegate. You also can easily insert "stub code" to simulate the actual server interaction during the early stages of development.
The Application Tier
In this example, the Application Tier will be handled by a ColdFusion 8 installation. It will contain two Coldfusion components. These components are purposefully simple.
In this example, the Flex application will pass a LoginVO ActionScript object to the CairngormLogin.cfc's login method through a RemoteObject call. This will be mapped to a LoginVO.cfc object. If this LoginVO.cfc object has the username "david" and the password "password" the method will return true. If not, it will return false.
Code Example 6 - LoginVO.cfc
Code Example 7 - CairngormLogin.cfc
Application Code
Download (11 Kb)
Looking Ahead
There are only two tutorials remaining in the Cairngorm series. In the next tutorials you will learn about code generation options for Cairngorm, and you will also build an actual application using Cairngorm.
Reference
The following resouces should assist you in getting Flex connected to your application server.
Thanks a bunch for the tutorials David, they make learning this stuff SO much easier. If anyone else runs into problems implementing the ServiceLocator mxml component described above, make sure you have the component added to your Application mxml like you did with the FrontController. Took me a while to figure that one out.
@Jorsh – Thanks for this note! I apologize to all if I didn’t make this clear in the tutorial.
[...] Part 4 you saw the full Service to Worker pattern demonstrated. However, the method discussed in the last [...]
why can’t access ServiceLocator in the ERROR file?
Any idea?
GOT IT
Here is the error I get when running example. I have declared a remoteObject service and given id=”unclaimService”.
RemoteObject not found for unclaimService
at RemoteObjects/getService()[C:\dev\swat\projects\ac_emea\Cairngorm\com\adobe\cairngorm\business\RemoteObjects.as:80]
at com.adobe.cairngorm.business::ServiceLocator/getRemoteObject()[C:\dev\swat\projects\ac_emea\Cairngorm\com\adobe\cairngorm\business\ServiceLocator.as:137]
I am getting error at this line in the delegate class constructor.
When the command class tries to get instance of delegate, its throwing an error.
this.service = ServiceLocator.getInstance().getRemoteObject(”unclaimService”);
Also can somebody explain the logic behind the above line. We have created a services.mxml file and its rootTag is . I am kind of confused!!!, where are we using that services.mxml file… please explain!!
Hi David,
Great series of vedios….
I implement all these stuff but i got an error
ArgumentError: Error #1063: Argument count
Could you help me to resolve this ?
ThanX in advance………
Hello David
Thanks a lot for the wonderful series of tutorials. This has got me going with Cairngorm.
I am setting up the Services using Zend_AMF. The service works fine when I use a simple RemoteObject without Cairngorm. But using this tutorial the fault event displays the following message:
[RPC Fault faultString="Channel disconnected" faultCode="Client.Error.DeliveryInDoubt" faultDetail="Channel disconnected before an acknowledgement was received"]
What could be going in this case? Can you guide me appropriately?
With Kind Regards
Vikram
Hello there David
I just noticed that the service class you made in ColdFusion takes in the argument loginAttempt of type LoginVO.
I am implementing the service in PHP. Should it be same there or will it take two arguments username and password?
Thanks and Regards
Vikram
To newbie developers who use this wonderful tutorial by David, but create the server side service in PHP, please remember that in LoginDelegate.as, you will have to change the method which calls the server-side method like this
public function login(login:LoginVO):void {
var call:Object = service.login( login.username, login.password );
call.addResponder( responder );
}
This applies when you create the service in PHP which has the prototype like this..
public function login($username, $password)
{
// implement login functionality here
}
I had to spend quite sometime figuring this out, being a newbie in Cairngorm and Flex.
With best regards
Vikram
Hi David.
Thnaks a ton for Gr8 articles about Cairngorm.
As a newbee I have one problem
In Cairngorm view fires cairngorm events which are routed to appropriate commands and these commands then update the model.
As model is bound to view view gets updated.
But if I want want to clear the user registration form after sucessfully inserting the record into data base what is the best method to do that, if I am using Cairngorm.
Please Help
[...] Artigo sobre Cairngorm parte 4 e o Vídeo Cairngorm Part 4 [...]
For those that were getting the on this line.
this.service = ServiceLocator.getInstance().getRemoteObject(”unclaimService”);
I was getting the same thing. Then I made a reference in my main application to the services and it worked fine.
(put this in your main application, it defines the service before making the call).