Cannot perform web service invocation – Premature end of file

July 12th, 2010 Gareth 2 comments

I’ve been getting a ColdFusion error on a remote server that I’m not getting when testing locally so obviously something is different between those 2 servers. I had thought to just try using a webservice call to the remote server to see if I could debug it better (the error I’m getting in Flex isn’t detailed enough to begin to track down the issue). The webservice I was testing is supposed to return back a complex object, but I was getting the error

Cannot perform web service invocation – Premature end of file

If I tested a return of just a string, it worked, but it did not like returning the complex object. After browsing around via Google for a bit, it seems that it may be related to nulls being returned in my complex object. Now I’m not sure how to fix this other than to add default values to my objects when they are returned (which I really don’t want, or *need* to do as calling it via Flash remoting works nicely), but debugging them via CF, not so optimal.

Antennae – Automated Builds for Flex

June 22nd, 2010 Gareth 1 comment

My company pushes code out to our dev, QA, and production servers via ANT scripts. They’re an excellent way to deliver your code in a reproducible fashion that takes away (most) of the human interaction necessary, and hopefully most of the spots where errors could be introduced. This method has been working great for our ColdFusion builds (as there’s nothing that gets compiled each time), but pushing out our Flex code has been more of a challenge.

We use subversion to version control all of our mxml and actionscript files, and also our swf files. Currently we build our swf files locally, deliver them to our ColdFusion stream, and check them into our SVN repository. This works great until you forget to update your Flex files before building your SWF (as I have done), removing functionality that another developer added. Not a huge issue, but by using some kind of automated build process, you can circumvent this issue very easily. This is where Antennae comes into play.

By adding a few xml files to your directory structure, you can use Antennae to handle the initial directory structure creation, html-wrapper, compiling, unit testing, and several other things that slip my mind right now :)

Hopefully soon I’ll be able to make some posts about how I managed to set this up that will assist others in automating their Flex builds.

Global Error Handler in Flash

August 12th, 2009 Gareth No comments

Ever wanted to be able to have some kind of global error handler in your Flex/Flash application? I know I have, every time I’ve had to add try and catch all over the place “just in case” my app throws an error. Please, please, please go and vote this feature request up at Adobe Jira

Ability to intercept system error dialogs

This will go a long way in saving us all a lot of pain in error handling.

Categories: Errors, Flex, Framework Tags: , ,

My code is going to be in the Flex SDK

July 28th, 2009 Gareth 2 comments

A little while back Nate Beck and Marty Mickelson set up the Bug Quash event to promote users to give back to the Flex SDK that they all work with each day by submitting bug fixes. Just from working with Flex everyday, we’ve probably all come across at least one bug that had us beating our heads against the wall thinking that we were doing something wrong, when there was actually something a little wonky with the Flex SDK. As Flex is open source, it allows for anyone to submit a patch for review by Adobe, and, once you set up your local environment (and set up your sandbox account), there’s really no good excuse not to try to fix something. Plus, it helps you to understand the code you’re working with at a more fine grained level, rather than just taking for granted that Flex “just works”.

I attended the first BugQuash, but only late in the day, so I didn’t get to fix anything at the time. Still wanting to fix a bug, I decided I’d check out the bug listings of at the Adobe Bug System. As I’d worked with the date functions in Flex quite a bit for my Flex Date Utils library, I figured I’d try to find something to do with dates in the bug base. In checking through, I came across this little one. I wanted to take something that wouldn’t be too crazy to accomplish for my first fix, but was at least useful to add.

I submitted the first patch back in April (a month or so after the BugQuash finished). It took me a little while to get my environment set up (Nate gave a little video demonstration of how to set up your environment here so check it out if you’re thinking of contributing), but once I did, it was pretty painless. I got some feedback (I’m not sure whether it was a user or someone at Adobe) on the patch and made the suggested changes, resubmitted back in June, and today my patch just got approved :) Turnaround wasn’t too bad considering that Flex 4 is in beta along with Flash Builder, ColdFusion Builder, CF9, and everything else going on at Adobe lately.

Now I just have to figure out which one I want to work on next. Plus, check out my “Bug Quash Badge”…also created by Mr Beck. It links up to the JIRA and queries for the number of bugs you have “quashed”. Excellent!

Categories: Flex, code Tags: , , ,

XMLSearch in ColdFusion – Unusual Behavior

July 8th, 2009 Gareth 5 comments

Well, maybe not completely unusual behavior, but I figured I would document my findings for others anyway.

ColdFusion allows managing of XML documents with relative ease. From the dot notation for traversing an XML document to the various functions to manipulate the document, just about everything is pretty simple when using ColdFusion. Recently, however, I came across an issue with using XMLSearch() It’s probably more of my (previous) understanding of the function call itself rather than it not working correctly, but it still seems a little unusual behavior to me.

I had an XML document that parsed fine.

<cfset INST.parsedData = xmlParse( INST.config ) />

From here I did an XMLSearch for a certain type attribute in my parsed document:

(I grab the first item of the array and set it back to itself so I’m not creating an extra temp variable. The @type is always present in the file so no error will be thrown)

<cfset INST.subObject = xmlSearch( INST.parsedData, "//object[ @type= '" & INST.eachType & "']/") />
<cfset INST.subObject = INST.subObject[ 1 ] />

From here, I wanted to grab a specific item from INST.subObject, but doing the following would always return all of the property nodes with identity=”true” rather than just those specific to the INST.subObject variable

<cfset INST.identityProperty = xmlSearch( INST.subObject, "//property[ @identity= 'true']") />

I guess that the INST.subObject is actually just a pointer of some sort to the original document and when passing the xmlDoc argument into xmlSearch, it then uses the whole original document to perform the actual search.

The solution isn’t too difficult, but may not be completely apparent at first. You just have to create a new xml document of the returned data, thus wiping out any references to the original parsed XML document.

<cfset INST.subObject = xmlparse( tostring( INST.subObject[ 1 ] ) ) />
<cfset INST.identityProperty = xmlSearch( INST.subObject, "//property[ @identity= 'true']") />

INST.identityProperty will now contain the one node within INST.subObject that has an attribute “identity” of true (rather than returning all nodes in the original document with attribute “identity” of true).

Categories: ColdFusion, Errors, code Tags: , ,

Builder Design Pattern In ColdFusion

May 19th, 2009 Gareth No comments

Recently at work, I had been puzzling over object creation and sub-object creation within each of those objects (e.g. how do I create deep nested objects without bringing down my database server and my ColdFusion server trying to loop over everything). After checking out the design patterns books, and the good ol’ Gang Of Four (GoF) book, the solution that seemed to meet our needs the best was the Builder design pattern. This will probably just be a general overview to start with and then I’ll try to get into some of the code, and ideas I implemented to make all of this happen, and in a relatively efficient manner.

In order to create all of the objects, I wanted to have as much autonomy and encapsulation as possible, so that no parent need know how their own child objects are created…the only thing they would know is which child objects make up “themselves” (if that makes sense to anyone other than myself :) ). So, in order to accomplish this, all objects that need to be built start off with a director.

The director knows how to build itself and which objects it is composed of. The director (in my use of the pattern) calls other directors to build the objects that it is composed of. For example, if a User object is composed of a role object, and an organizational unit object, these would both have their own directors, RoleDirector and OrganizationUnitDirector, which would also build them, along with all of the basic properties of the User object, and return them back to the UserDirector to build all of the composed object. The basic properties of the User would be created in a Builder, the UserBuilder, which would also handle (in my case) returning identity values for attaching the role object and organizational unit objects to each User object in the director.

In order to reduce the amount of database calls, I wanted to get all of the necessary objects for all of the top level parent objects at once. For example, if I had 50 users that were being built, I wanted to query the database for role objects for all 50 users, and the same for the organizational unit objects. This way, no matter how many objects I had, the total number of database calls would be equal to the number of objects that composed the top level parent object. In this case a User with a role object and an organizational unit would be 3 total database calls (one call the get the 50 users, 1 to get the role data and 1 to get the organizational unit data). If each one of the child objects had a child object, that would still be only 2 more database calls. If I handled this as each object was being built, it would be 50 users * 3, or 150 database calls…and so on, and so on, so quite a bit of savings to the database. The only problem I then had was how to call the database without using the “WHERE…IN” statement which we’re all told to avoid like the plague, or at least try something else if at all possible.

I had chatted with our DBA to see if there was a better solution than just passing a huge list of IDs to a WHERE…IN statement and he suggested using a solution he came up with that actually parsed out the IDs from a list and places them into a table that can be joined on just like any other table. This is the method he felt would allow us to use the method described above while still keeping pretty good efficiency from the database. I’d also asked about moving to stored procedure calls which should also allow for some improved efficiency…maybe not a lot, but at least it keeps the database management contained in a central area. For testing, I kept with the WHERE…IN, but once we move to production, I’m going to push as much as possible to stored procedures with no WHERE…IN allowed :) …no really good reason to keep them in the code, but several good reasons to push them out.

My final problem was when building the objects in the director, how could I access all of these objects that my other directors had created without having to loop over arrays of objects over and over again in order to get at the data I needed. As structs in ColdFusion can be called via Associative Arrays, I figured why not come up with a solution to create an associate array using some kind of value that is passed in from the calling Director, that could be used as a reference when needing a specific object from that associative array. Thus, taking a note or 2 from Flex, I created the ColdFusion ArrayCollection.

I’m going to stop now, but I’ll hopefully be able to take a few of these ideas and show how I went about creating the directors, builders, the ArrayCollection object, and perhaps even the database portion. I’ll at least go more in depth about the whole layout of things. I’m supposed to document this for work, so perhaps this will become a nice document for them to use also :)

Subclipse 1.6 changes highlight and comment colors in CFEclipse

April 6th, 2009 Gareth 9 comments

I just installed Subclipse 1.6 in my Flex Builder as there was some conflict between it and my TortoiseSVN install. I like to do my commits and updates via Eclipse so I’m not switching out to my Explorer window for quick commits. If there is any conflict resolution needed, or I need a little more fine grained control, I switch out to Tortoise (as Subclipse doesn’t do as good a job currently).

After I upgraded from Subclipse 1.4 to 1.6, for some reason (I pretty sure it was Subclipse as I didn’t upgrade anything else), it decided that it didn’t like my comment color in CFEclipse or my highlight color and decided to randomly alter those colors to something else…a really weird, dark green for the comment background color and a much darker shade of blue for the text highlight color. To my mild case of OCD, that is just unacceptable :) Plus it’s just really difficult to read *any* text with a dark green background

If you want to switch these options back to their original colors, do the following:
Window -> Preferences -> CFEclipse -> Editor -> CFML Colours -> CFML Comment Background
I switched this one back to white from dark green.
and
Window -> Preferences -> CFEclipse -> Editor -> Appearance color options -> Selection background color
This one I had to create a new custom color and set it to Red 49, Green 106, and Blue 197 (this, I think, is the windows highlight color).

So far these are the only things I’ve found that it changes. I’ll post new updates if I find anything else.

Adding colspan to a datagrid

March 17th, 2009 Gareth 11 comments

Recently at my job, our User Interface guru came up with the design and interface that she wanted for our users. However, the design she came up with required adding a colspan to a datagrid. As many know who have tried it, this is not really a possibility right out of the box with a Flex DataGrid. It is apparently a possibility with the AdvancedDataGrid, but I have just never really liked the visuals of the datagrid, especially with how it outputs the rows of data…it seems very cluttered to me when grouping is added. Plus, I have a PagedArrayCollection that I wrote and use quite regularly, that (currently) does not play nicely with the AdvancedDataGrid (I think it has something to do with the grouping), and currently just works with the regular DataGrid. So, in order to accommodate the business and my PagedArrayCollection, rather than just have multiple rows of data in multiple columns, I came up with a solution to allow for the spanning of multiple columns, as many as is necessary.

I tried to figure out, visually and programmatically, I could mimic the HTML table colspan. My solution actually involves 2 datagrids + single datagrids as itemrenderers within the rows. As Flex recycles its itemrenderers, this appeared to be a pretty practical solution. My first datagrid is used solely for the headers. I made the height of the datagrid match the height of the headers of the first datagrid, so all that is visible is the headers themselves.

DataGrid Header

DataGrid Header

The code for this is as follows (notice the small height of the datagrid):

<mx:DataGrid id="headerDataGrid" x="70" y="40" width="780" height="23" dataProvider="{ dataProvider }">
	<mx:columns>
		<mx:DataGridColumn headerText="Name" dataField="name"/>
		<mx:DataGridColumn headerText="Location" dataField="location"/>
		<mx:DataGridColumn headerText="Exp" dataField="exp"/>
	</mx:columns>
</mx:DataGrid>

From here I created another datagrid, but this one contains only a single column. I also removed the headers from this datagrid as I will be using the datagrid headers from the previously created datagrid (headerDataGrid), so this one just looks like the rows from a datagrid.

DataGrid Body

DataGrid Body

Once I had these 2 datagrids, I put them right next to each other so it looks like they’re actually the same datagrid, but without vertical lines between the columns.

The code for the 2nd grid is:

<mx:DataGrid x="70" y="61" id="dgMain" width="780" height="444" showHeaders="false" dataProvider="{ dataProvider }" paddingTop="0" paddingBottom="0"
	variableRowHeight="true" selectable="true">
	<mx:columns>
		<mx:DataGridColumn headerText="All data" dataField="col1" itemRenderer="com.flexoop.utility.renderer.ColSpanRowRenderer" />
	</mx:columns>
</mx:DataGrid>

Both of these datagrids are bound to the same dataprovider. This makes manipulation of the arraycollection extremely simple. I had thought I would be writing my own sort and filter functions, overriding the headers, but I forgot that once these datagrids are bound to the same arraycollection, Flex automatically handles all of that and everything just works. Simple! :) The headertext and dataField are irrelevant in this datagrid as they will not be used. I set the variableRowHeight=”true” so the itemrenderer will show the multiple rows of data correctly.

As you can see from the above code, I created a ColSpanRowRenderer itemRenderer. This handles the final part of the colspanned datagrid…the actual colspan.

ColSpan Row Renderer

ColSpan Row Renderer

The code for this looks like:

<mx:DataGrid id="dgLocal" x="0" y="0" width="100%" showHeaders="false" height="23" dataProvider="{ data }" backgroundAlpha="0" selectable="false"
	borderSides="{ parentDocument.detailed ? 'bottom top' : 'bottom' }">
	<mx:columns>
		<mx:DataGridColumn headerText="Name" dataField="name" />
		<mx:DataGridColumn headerText="Location" dataField="location" />
		<mx:DataGridColumn headerText="Exp" dataField="exp" />
	</mx:columns>
</mx:DataGrid>
<mx:Text visible="{ parentDocument.detailed }" includeInLayout="{ parentDocument.detailed }"
	htmlText="This is where the detailed text will go.&lt;br /&gt;This is not formatted now but can be once it goes live" y="22" width="100%" />

This is all contained within a VBox with all padding set to zero to aid in visual layout, and to make it look like it is a row in the dgMainBody datagrid. The height of the datagrid forces it to just show the single row of data, with showHeaders=”false” again. I bind it to the “data” value that is passed in to the itemrenderer, then output the properties of that data object within the single row datagrid. I have a variable named “detailed” in the parentDocument (the page containing my header and main body datagrids). This allows me to show or hide the extra colspanned row of data. This was part of the requirement from the business, so I added it in. As the header, main body, and colspanrowrenderers all need to be tightly coupled, I was not so worried about referring to the “parentDocument”. Had this been something I was going to be moving around to other components, I would have tried to think of another solution. The “includeInLayout” attribute will completely remove the “Text” box from the view, so as not to take up any space when it is not visible. In order to prevent the user from selecting the single row datagrid item, I set ‘selectable=”false”‘, then in the outer datagrid (dgMainBody), I set ‘selectable=”true”‘. This will then allow the user to select the complete itemrenderer (both datagrid row and colspanned text field).

I had found that when detailed=’false’, the single datagrid rows did not alternate colors, which made sense as they were all the first row. In order to fix this problem, I set backgroundAlpha=”0″ in the colspanrowrenderer. This then used the colors of the dgMainBody datagrid for coloring the itemrenderer. The final visual part was setting the borderSides=”bottom” or “bottom top” depending on whether the view was detailed or not.

The final part of getting this to look and act like a regular datagrid was to adjust the column widths of all of the ColSpanRowRenderer rows when the header items were moved, as the rows are not actually linked directly back to the dgHeader. To catch these changes, I added a creationComplete=”init()” to the vbox in my ColSpanRowRenderer. Then in my init() function (along with a setColumnWidth function):

private function init():void {
	setColumnWidth();
	parentDocument.headerDataGrid.addEventListener( DataGridEvent.COLUMN_STRETCH, setColumnWidth );
}
private function setColumnWidth( event:DataGridEvent=null ):void {
	var _i:uint = 0;
	var _length:uint = parentDocument.headerDataGrid.columns.length;
	while ( _i < _length ) {
		dgLocal.columns[ _i ].width = parentDocument.headerDataGrid.columns[ _i ].width;
		_i++;
	}
}

At first, I was only changing the width of the column that was being stretched, but I found that the flash player must do some other computations on the other columns, so I just decided to loop over all of the columns and resize each one to match the header columns. I found that I had to add a ‘render=”setColumnWidth()”‘ also as some of my columns were a little screwy at times. This adds a slight adjustment after the page renders, but is not all that noticeable and fixes any column width issues I was having.

So the final product looks like this:

DataGrid With ColSpan

DataGrid With ColSpan

And code is DataGridColSpan.mxml and ColSpanRowRenderer.mxml

Hopefully I haven’t bored anyone to tears with my explanation, but I wanted to be sure that everyone understands my reasoning for doing everything that I did to the datagrids. Enjoy!

Categories: Component, Flex, code Tags: , , ,

Update to MenuItem class

February 24th, 2009 Gareth 2 comments

I have recently begun using my MenuItem and MenuItemWithChildren classes at my work, and have made a slight modification to the code to lessen some of the code writing required.

As I was using the menuItem class, I realized that when I selected the item, I was usually just calling some function based upon the label of that menu item. Using my updated MenuItem class, you can now pass in a function as one of the parameters.

My MenuItem class now looks like this:

package com.flexoop.utility {
 
	[Bindable]
	public class MenuItem {
 
		/***********************************
		 * properties
		 **********************************/
 
		private var _enabled:Boolean = true;
		private var _groupName:String = "";
		private var _icon:Class;
		private var _label:String = "";
		private var _menuHandler:Function;
		private var _toggled:Boolean = true;
		private var _type:String = "";
 
		/***********************************
		 * getters
		 **********************************/
 
		public function get enabled():Boolean {
			return this._enabled;
		}
 
		public function get groupName():String {
			return this._groupName;
		}
 
		public function get icon():Class {
			return this._icon;
		}
 
		public function get label():String {
			return this._label;
		}
 
		public function get menuHandler():Function {
			return this._menuHandler;
		}
 
		public function get toggled():Boolean {
			return this._toggled;
		}
 
		public function get type():String {
			return this._type;
		}
 
		/***********************************
		 * setters
		 **********************************/
 
		public function set enabled( value:Boolean ):void {
			this._enabled = value;
		}
 
		public function set groupName( value:String ):void {
			this._groupName = value;
		}
 
		public function set icon( value:Class ):void {
			this._icon = value;
		}
 
		public function set label( value:String ):void {
			this._label = value;
		}
 
		public function set menuHandler( value:Function ):void {
			this._menuHandler = value;
		}
 
		public function set toggled( value:Boolean ):void {
			this._toggled = value;
		}
 
		[Inspectable(enumeration=separator,check,radio,normal)]
		public function set type( value:String ):void {
			this._type = value;
		}
 
		public function MenuItem( label:String="", menuHandler:Function=null, enabled:Boolean=true, type:String="normal", toggled:Boolean=true, groupName:String="", icon:Class=null ) {
			this.enabled = enabled;
			this.groupName = groupName;
			this.icon = icon;
			this.label = label;
			this.menuHandler = menuHandler;
			this.toggled = toggled;
			this.type = type;
		}
 
	}
}

And similarly for the MenuItemWithChildren class:

package com.flexoop.utility {
 
	public class MenuItemWithChildren extends MenuItem {
 
		/***********************************
		 * properties
		 **********************************/
 
		private var _children:Array = [];
 
		/***********************************
		 * getters
		 **********************************/
 
		public function get children():Array {
			return this._children;
		}
 
		/***********************************
		 * setters
		 **********************************/
 
		public function set children( value:Array ):void {
			this._children = value;
		}
 
		public function MenuItemWithChildren( label:String="", menuHandler:Function=null, enabled:Boolean=true, type:String="normal", toggled:Boolean=true, groupName:String="", icon:Class=null ) {
			super( label, menuHandler, enabled, type, toggled, groupName, icon );
		}
 
	}
}

The 2nd parameter is now the menuHandler function. So in order to use this, you could set up something like this:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()" xmlns:flexoop="com.flexoop.utility.*">
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
 
			import mx.events.MenuEvent;
			import mx.controls.Alert;
 
			import com.flexoop.utility.MenuItemWithChildren;
			import com.flexoop.utility.MenuItem;
 
			[Bindable] private var menuData:ArrayCollection = new ArrayCollection;
 
			public function init():void {
				var menuItem:MenuItemWithChildren = new MenuItemWithChildren( "test 1", showMe );
				menuItem.children.push( new MenuItem( "test 4", showMe ) );
				menuItem.children.push( new MenuItem( "test 5", showMe ) );
				menuData.addItem( menuItem );
				menuData.addItem( new MenuItem( "test2", showMe ) );
				menuData.addItem( new MenuItem( "test3", showMe ) );
				mb.dataProvider = menuData;
 
			}
 
			private function menuItemHandler( event:MenuEvent ):void {
				( event.item as MenuItem ).menuHandler();
			}
 
			private function showMe():void {
				Alert.show( 'this was fired from my menuItem' );
			}
 
		]]>
	</mx:Script>
	<mx:VBox>
		<mx:ApplicationControlBar id="acb">
			<mx:MenuBar id="mb" dataProvider="{ menuData }" click="menuItemHandler( event )" />
		</mx:ApplicationControlBar>
	</mx:VBox>
</mx:Application>

(I didn’t get a chance to test the above example code so, if anyone finds that something doesn’t work correctly, feel free to ping me about it and I’ll try to get it working properly). It’s a somewhat basic example as all items point to the same function, but it would be very simple to alter this so each menuItem points to a separate method instead, or pass a certain value to the function to display.

wmode – one little attribute makes all the difference

February 3rd, 2009 Gareth 2 comments

At my work, the business wanted a right click menu that did not have all of the default “Flash” items in it. Now, you can edit the context menu so that it hides *most* of the Flash options, but not all of them. I found a right click someone wrote that uses Javascript to intercept the right click event from the mouse before it propagates to the Flash swf. I created a right click class (I may show that class at some point) that handles the resulting event that Javascript passes and generates the menu options to the user. However, for some reason (although I was using what I thought was identical code to another page a co-worker wrote), I wasn’t able to get the right click to work. It kept showing the regular context menu. After puzzling over the code for about an hour, I then went digging through the html page. After comparing the code for a few minutes, I came across the “wmode=’transparent’” attribute added to the swf creation. “Of course”, I said to myself. The right click was not able to be intercepted by the page before it got to the swf, as the right click was always hitting the swf first. By setting the wmode to transparent (I’m guessing here slightly), gets caught by the page, rather than the swf. The Javascript can then fire off a callback event to the Flex/Flash swf, which then makes everything work great. Such a simple little attribute that is so vitally important.