Login System For A Flex Application With ColdFusion Backend Part 6 - Handle Registration Errors
Introduction to Part 6 - Handle Registration Errors
One of the business rules my login and registration system has to follow is that each user name and email in the system must be unique. If you look back at part 1, I set the databases table up with constraints so that the database will generate an error if an attempt is made to insert a record with a user name or email that already exists in some other record. In this part of my design, I add logic to handle those errors when Flex calls the createMemberService CFC function to add a Member object to the Member table and that Member object has a user name or email that already exists in the table.
You can view a working demo of the part of the design (right click on the application to view the source code).
Handling Errors During the Registration Process
When a user clicks on the Register button, my Flex application creates a Member object using the user's input and then calls the createMemberService CFC function. Below is the function in my Flex application that is called automatically, when the CFC createMemberService function returns an error. As I noted above the error may be because the user name or email already exist in the Member table.
private function faultCreateMemberService(event:FaultEvent):void{
//Alert.show( ObjectUtil.toString(event.fault) );
//will search for email or in the error
//i means case insensitive
var emailRE:RegExp = /email/i;
var userNameRE:RegExp = /username/i;
var errorStr:String = event.fault.faultString;
if ( errorStr.search(emailRE) > -1 ) {
//if the errorTxt object already exists
//remove it from the display
if (errorTxt != null) {
this.removeChild(errorTxt);
}//end if (errorTxt != null)
//create the Text object
//and set its style attributes
errorTxt = new Text();
errorTxt.width=300;
errorTxt.text = "Error! Email aleady exists. Enter a different email.";
errorTxt.setStyle('color','red');
errorTxt.setStyle('fontSize','14');
errorTxt.setStyle('fontWeight', 'bold');
//add the Text object to this Form at position 4
//should be just above the email text input field
this.addChildAt(errorTxt,4);
} //end if (errorStr.search(emailRE) > 1)...
if (errorStr.search(userNameRE) > -1 ) {
//if the errorTxt object already exists
//remove it from the display
if (errorTxt != null) {
this.removeChild(errorTxt);
}//end if (errorTxt != null)
//create the Text object
//and set its style attributes
errorTxt = new Text();
errorTxt.width=300;
errorTxt.text = "Error! User name aleady exists. Enter a different user name.";
errorTxt.setStyle('color','red');
errorTxt.setStyle('fontSize','14');
errorTxt.setStyle('fontWeight', 'bold');
//add the Text object to this Form at position 5
//should be just above the user name text input field
this.addChildAt(errorTxt,5);
}//end if (errorStr.search(userNameRE) > -1 )
}//end function faultCreateMemberService
In the above function, I create two Regular Expression objects, one for email and one for username. I assign to the errorStr the event.fault.faultString which contains the error message from the database. I search through the errorStr for an occurrence of the emailRE and if there is match I create an errorTxt Text object and add it to components being displayed. I do the same process for searching for the userNameRE.
The advantage of using the database to maintain the unique email and user name business rule, is that I only need to call the createMemberService CFC to insert the Member object into the table. I don't need to first search through the table for the user name and email provided to see if they already exist.
Note the code where I check to see if errorTxt != null. If the errorTxt Text object already exists, it means a previous error was found and displayed to the user. So I need to remove that errorTxt Text object from the display before creating and showing the user a new errorTxt object.
Conclusion
I've now satisfied both use cases I described at the beginning of this series. But after completing this iteration of the design, I can see that I need to address one more use case: User doesn't remember his user name and/or password. User click on a Forgot user name/password link. User enters email address. If email address is found, send user name and password to that email address. Notify user that user name and password were emailed. If email address is not found, notify user that email address was not found.
I'll address the above use case in the next iteration.
Between all your work in this series and the roles-based tute, I have been thinking I could build such an app-shell that would, per role, load a module into the application - and I'd be off to the races.
However I just spent a couple of days trying to get this into both Access and MySQL (my box won't handle any more software, it's old and barely chugs along with MySQL - though I do have a SuperMicro box being built...yippie), but I can't seem to connect to the db, to read or write, though I'm not being thrown any CFC errors. So I'm guessing the db itself MUST be SQL 2005? Is that the case? I tried running the sql script in MySQL but it threw me errors I'm guessing because of the "IDENTITY(1,1)" - that's just a guess. Cobbling together an Access db seems to cause no fuss on the part of the app, but none of the updates when registering get entered, nor even when I manually put in a user can I get it to read in to the application. I added brucephillips>GeekNews folders and threw the CF stuff in there (under the Flex root) and even set a mapping in CF Administrator, so I'm guessing the disconnect is in the fact I'm not using SQL 2005?
I'm able to get both Access and MySQL 5 working fine for anything else with no problems usually.
Do I need to wait for a box that has SQL 2005 on it before I can get this up and running so I can play with it?
Thanks very much for your hard work - you're helping people like me a lot!
Shawn
So if you want to use the tutorial code "as it is" then you need the backend database system to be SQL Server 2005 (either express or the full version).
However, the CFC DAOs code can be easily changed to work with any backend database (MySQL or Access).
The key is to get your database setup correctly with the same schema (fields/tables) as my tutorial. Then change the DAOs to work with your database setup. Then create a datasource in CF admin to connect CF to your database. Then run some tests of the CFC DAOs in CF to ensure everything is working in CF before you start the Flex part.
I'd much rather be able to get into your work than just stand by waiting...
Thanks very much for your quick help:) Looking forward to seeing it run in Flex from my localhost:)
Shawn
Question (great stuff by the way), we have a login for our site. However lets say a person bookmarks a certain page within the site on a previous visit and decides to revisit that section of our site, they are then prompted to the login screen. After logging in, they are taken to our 'home directory'where they can then navigate to their original request. Is their a method do you know of that can 'take' them to their original request without going through a generic 'home directory'?
Any insight would be great.
thanks!
In ActionScript capture the URL the person is using
After person logs in, use ActionScript to restore the state of your application to match the URL the person used (ie the deep link).
I recall something about Flex 3 making deep linking easier...
I am new to Flex and have been reading a lot of info on it, but your login form example is really good. I am using Java as my backend so it does not completely apply, but I got the general idea and now I can probably create something similar that works with java.
Thanks!
I have easily been able to apply your methods to my access database system.
I love how its set out...nice and clear.
Works like a charm.
Thank god for google...otherwise I would never have found this.
cheers and thanks Mark
Thanks,
Shariff