explorers' club

explorations in dev, science, sci-fi, games, and other fun stuff!

Tutorial: handling service validation errors & cairngorm

6 Comments

client-side validation

In general validation takes place in two places within a RIA: the client and the services. Generally when creating a services-enabled flex application, you try to validate some of that data on the client. For instance, you want to check for necessary data (e.g. required form fields) and properly formed data (e.g. making sure an email address has the @ sign and a domain). This is what I call client-side validation. So what do I mean by “service validation errors”?

service validation

Let’s use the example of sending some registration data to a service. We the flex client have already validated the data and send it off. So let us assume we are sending a user name, password and email address. Obviously we want our user name to be unique and the flex client hasn’t a way to determine this. Instead it relies on some registration service to check for the uniqueness of the data being sent. Ok, let’s assume now that we have sent something that is already being used by another user. This is service validation (it may be called something entirely different which I am ignorant of, but this is what I call it for now). Now if you have a good system in place, you will want to get some data associated with the registration error that just occurred. So now that we are on the same page about the high level validation stuff let’s get a closer view in handling it in an application that uses Cairngorm

user experience ground rules

Firstly I am going to set some ground rules for an application. We are going to assume that any view whose data requires a service and validation response will prompt further user input within itself. So no popups/Alerts on top of some registration popup/view. Why not? Well these solutions came about from my client’s user experience design that doesn’t allow for such simple solutions. Plus it would negate the whole purpose of my posting 😉

under-the-hood-process

  1. user enters data requiring validation
  2. client-side validation occurs (assume it passes)
  3. Cairngorm event dispatches with data
  4. command (I am scrapping delegates for the sake of simplicity) process sends out and awaits reponse
  5. service validation errors come back with response necessitating changes to data
  6. command needs to notify someone that data needs to be corrected

method one: referencing

For the OOP purist out there, this might not settle well. It certainly did not settle well with me. But it’s a pragmatic approach with very few pitfalls attached. For those familiar with AS2 and ARP this will be very familiar.

Firstly we need to establish some sort of protocol for handling the service validation errors coming back. A very simple and forceful solution would be to use an interface. Let’s call it IServiceValidationClient. Yeah that sucks but it gets the point across. Here is a glimpse of that interface:

package com.foo.validation
{
	public interface IServiceValidationClient
	{
		function handleValidationErrors (errors:Array):void;
	}
}

Our view will implement this interface. Now to make use of it. We need pass a reference of this implementor along with the call. Depending how hairy your application is, you may have tons of custom CairngormEvent subclasses. For simplicity, I will just use a basic subclass called FooEvent. It looks like this:

package com.foo.events
{
	import com.adobe.cairngorm.control.CairngormEvent;
	import com.adobe.cairngorm.vo.IValueObject;
	import com.foo.ui.IServiceValidationClient;

	import flash.events.Event;

	public class FooEvent extends CairngormEvent
	{
		public var vo:IValueObject;
		public var serviceValidationClient:IServiceValidationClient;

		public function FooEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false)
		{
			super(type, bubbles, cancelable);
		}

		override public function clone ():Event
		{
			var evt:FooEvent = new FooEvent(type, bubbles, cancelable);
			evt.vo = vo;
			evt.serviceValidationClient = serviceValidationClient;

			return evt;
		}
	}
}

So before we dispatch the FooEvent, we just say:

var evt:FooEvent = new FooEvent("doRegistrationDude");
evt.vo /* = the value object you should have assembled from the view's inputs */
evt.serviceValidationClient = this;

Ok, so at this point we are now dealing with the command. Upon execution, you need to store an instance level reference to the event.serviceValidationClient. This way you can grab it upon the response. If there happens to be an issue with the response, assuming you have standardized the errors somehow, you just grab that reference again and say:

serviceValidationClient.handleValidationErrors(errors);

Now there is one thing left to do. And this is very important. You need to do some clean up after you have utilized the response data. In this call you to make the command’s ref to the view null again or it will not get garbage collected.

serviceValidationClient = null;

Summary

pros:

  • simple implementation
  • provides an interface for standardization of error handling
  • requires very little in additional coding/classes
  • not highly coupled

cons:

  • not very OOP
  • requires that you remember to implement the interface
  • requires garbage collection clean up

Ok so that is method one. I will post the other two methods in separate posts so as to make a short read of them.

Advertisements

6 thoughts on “Tutorial: handling service validation errors & cairngorm

  1. Pingback: Tutorial: handling service validation errors & cairngorm - part 2 « explorers’ club

  2. Pingback: Tutorial: handling service validation errors & cairngorm - part 3 « explorers’ club

  3. Hi,
    There is one thing I’m not sure I understand – you set the reference to the view to null, meaning that the command will not “see” the view, and therefore the gc would later be able to kill the view (if it’s not reference in any other place).
    However, commands, usually has very short lifetime, that starts when they’re being called by the controller and usually end (when it’s a reasponder) at the result()/fault().

    Maybe you meant that teh view will not keep reference to the command, but that’s actually shuld never happen, because it doesn’t have any reference to commands.

    This topic is really interesting for me, and I’ll keep reading your series.

    Best regards,

    Almog Kurtser

  4. Hi Almog.

    I am not savvy about garbage collection or how to really optimize for it. I am under the impression that in order for the command to get collected, it needs to sever all links to outside persistent classes. Am I incorrect in this line of thinking? If so, then that makes method one even easier to implement because you needn’t worry about cleaning it up afterwards.

    Thanks,
    Justin

  5. Hi Justin,

    If your intent was to set the command ready for garbage collection, then you don’t have to null the command’s serviceValidationClient.
    Usually, the only one that has reference to the command is the FrontController that executes it, and potentially, a delegate that receives a reference to the command. other than that, I can’t think of any entity that would need such reference, expect for EventDispatcher objects which the command can listen to, like some emm…lets say Sound object, but that can be weak reference too, so it can be count off).

    If no reference is held to the command, it’s free for the gc, even if the command itself has reference to all kind of objects (like the model locator for instance).

    Cheers,
    Almog Kurtser

  6. @Almog

    Well that makes a lot of sense. So thanks for clearing that up. It seems then that method one is by far the easiest implementation since the command is still all-inclusive and nothing else has to worry about cleaning up the reference.

    Thanks,
    Justin

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s