Wednesday, December 29, 2010

CF: Railo 3.2 Released

After much work the Railo team released the new version (3.2) of Railo over Christmas.
Railo is one of the Open Source ColdFusion application engines available. The other notable one is Open Blue Dragon.
If you are doing ColdFusion based programming this is something that should belong to your stable of tools that you are familiar with.
In the past the discover-ability of Railo was harder as it was not as easy to understand how to get things going once you downloaded it. Though technically simply the step of getting it installed and going was a hurdle that made it harder than the Adobe engine.
With this release among a myriad of enhancement installers were made available for multiple platforms. For example, for the windows platform the comparable Railo installer is one third the size of Adobe's while it handles both 32 and 64 bit installations.

Happy Experimenting,
B.

Wednesday, December 1, 2010

XJS: Using the debugger command to start a debugging session

The ability to kick of the an in-line step-by-step debugger was introduced in JavaScript early on. Since before JS version 1.5, I believe. However, practically speaking there were few client-side debuggers that could take advantage of this.
Thus, the use of it has not been heavy even after the more ready availability of Browser development support and in-line debuggers. Today, all browsers support some sort of step-by-step debugger that can be used in concert with the debugger command to more effectively debug code, so perfect time to remind us of this option.

Why would we need to use it?. Let use this snippet as an example:

for (var i=0; i <= 10000; i++) {   
if (i==98) {

debugger;
}
}
Using conventional in-line debugging you would have to set a break-point, then iterate along until you reached the loop condition that you were interested in, i.e. 98. Using the debugger statement, you simplify this drastically.

Expanding this principle into use with ExtJS is easy. Giving the nested nature of much of the ExtJS code and heavy use of complex configuration objects setting breakpoints is sometimes a game of hit-and-miss.
Using the debbuger statement you will still able to halt the execution at the right place even if you did not hit the correct break-point in your debugging tool.

For example:

 1: listeners: {
2: render: {
3: fn: function(){

4: //stop for debugging here
5:
debugger;
6:
7: Ext.fly(clock.getEl().parent()).addClass('x-status-text-panel').createChild({cls:'spacer'});

8:
9: //Kick off the clock timer that updates the clock el every second:
10:
//Would need to be set in application format
11:
Ext.TaskMgr.start({

12: run: function(){
13: Ext.fly(clock.getEl()).update(new Date().format('g:i:s A'));

14: },
15: interval: 1000
16: });

17: },
18: delay: 100
19: }
20: }



Here we can stop when then rendering is activated to investigate code execution further.

The debugger statment works in most browsers, i.e. Firefox with Firebug, IE 8, Chrome. In IE you will have to explicitly put the browser in debugging mode by clicking the "Start Debugging" button in the developer tools.

Happy Debugging,
B.

Saturday, November 20, 2010

XJS: Avoiding of Anonymous Functions Example

One of the difficulties one faces quickly using the ExtJS framework is the code organization. Any project quickly grows into a jungle of anonymous functions and heavily nested configuration objects. Hard to read and hard to maintain.
Examples commonly start simple but as soon as more elements are added they turn off newbies. A configuration object spanning multiple screens is not easy to digest, but this is how most online examples are presented. This, according to my informal survey, discourages new developers from proceeding.
This, in my opinion, is one of the greater roadblocks to learning the framework and making scalable ExtJS apps. I understand that changes in ExtJS 4 will introduce a more mature MVC based application framework; however, the examples I have seen are still heavily reliant on multi-level nesting and anonymous functions.
It is of course, a matter of preference, but I do find organizing code written in that fashion harder to read and manage long term.
For once, common mistakes, such as missing a semicolon, comma, or bracket closure, result in disproportionate debugging time. On the other hand, having multiple team members working in their own "sandbox" is hard to do if everyone is trying to change the same file.
Thus, I was looking for alternate organization but could not find a simple example to show that another approach was possible.

Take this common ExtJS code as example (this is a fairly simple example in ExtJS realm). It draws a border layout based viewport:


Ext.onReady(function(){
new Ext.Viewport({

layout: 'border',
items: [{
region: 'north',

html: '<h1 class="x-panel-header">Page Title</h1>',
autoHeight: true,

border: false,
margins: '0 0 5 0'
}, {

region: 'west',
collapsible: true,
title: 'Navigation',

width: 200
// the west region might typically utilize a TreePanel or a Panel with Accordion layout
}, {
region: 'south',

title: 'Title for South Panel',
collapsible: true,
html: 'Information goes here',

id: 'southPanel',
split: true,
height: 100,

minHeight: 100
}, {
region: 'east',

title: 'Title for the Grid Panel',
collapsible: true,
split: true,

width: 200,
xtype: 'box'
// more nested code could be added here, e.g a GridPanel

}, {
region: 'center',
xtype: 'tabpanel', // TabPanel itself has no title

items: {
title: 'Default Tab',
html: 'Tab conent'
}
}]
});
});'


The formatting is nicely done, but still requires some getting used to. Only a few nested elements in this one yet the complexity can be already seen. What if you had a team of developers each working on one of the panels?

I prefer a more verbose but easier maintainable format that achieves the same result while allowing easier developer task separation (the use of multiple script tag is optional, I wanted to show a sense of separation of code):



<script type="text/javascript">
//we define a namespace to use for organization. This is optional.
Ext.namespace('startup');
</script>

<!-- panel definitions could be in another file -->
<script type="text/javascript">
// each panel could be seperate script file maintained by seperate developer or dynamically included via

// app server such as PHP / Railo / etc.
startup.northpanel = {
region: 'north',

html: '<h1 class="x-panel-header">Page Title</h1>',
autoHeight: true,

border: false,
margins: '0 0 5 0'
};


startup.westpanel = {
region: 'west',
collapsible: true,

title: 'Navigation',
width: 200
};

startup.southpanel = {

region: 'south',
title: 'Title for South Panel',
collapsible: true,

html: 'Information goes here',
id: 'southPanel',
split: true,

height: 100,
minHeight: 100
};


startup.centerpanel = {
region: 'center',
xtype: 'tabpanel', // TabPanel itself has no title

items: {
title: 'Default Tab',
html: 'Tab Conent.'

}
};

//assemble panels here into array, alternatly this array could be the items definition
startup.aItems = [startup.northpanel,startup.westpanel,startup.southpanel,startup.centerpanel];

</script>

<script type="text/javascript">
startup.DoInit = function () {

//create view port
var bport = new Ext.Viewport({
layout: 'border',

items: startup.aItems
});
}
</script>


<script type="text/javascript">
//the actual ExtJS onReady function remains very small
Ext.onReady(function(){
startup.DoInit();

}); //end onReady
</script>


Of course, there is the element of preference and argument about throw away functions, e.g. only run once; I would still prefer good naming and definition as this is the long run makes my life easier.

Feel free to comment.

Cheers,
-B

Tuesday, November 16, 2010

XJS: Sencha 2010 con impressions

I am attenting the Sencha (formerly ExtJS) developer conference to learn about the future. Overall good energy at this conference. Definite feel of excitement about product and company from the developer community. Here are some early impressions:
  • Lots of activity since the company got funding
  • Company is trying to grow up and it shows: products are beeing build out, revenue model is being decided on / experimented with, business processes look raw around the edges. Overall this puppy is growing up.
  • Sencha has many projects in the cooking pot with some very innovative ones in the mix while still putting good improvements into the existing ones. The question will be, is the company going to be able to pull all this off or are they overloaded. Deliveries could slip, quality could suffer etc.
  • Their bread and butter ExtJS 4 is getting a dose of good overwhaul inlcluding things I have been griping about for a while. The main thing for me is that a best practices application structure is now supported out of the box, so you can finally organize your code for larger apps in a meaningfull way. (Yeah!!!) . My impression is that there are still some challenges to overcome with backward compatibility which they are working on. Many more good things of course, hope they can pull it off.
  • The developer interest is increasing, 3 x the number of developers attended this year.
  • Keynote from at&t cto John Donovan (he loves all phones and all people, yeah very politically correct answers all the way). The nugget from him was the statement that HTML5 is a viable application plattform and mobile apps will be written in it more the future and at&t will support it on many devices with native device library connections. If you believe this, the future of Flash and Flex would look limited. Another conference attendee said "Adobe is the dead man walking". Wow!
  • The Sensha touch platform for mobile apps is going to be free. Cool.
  • Common Annoyance: "It works in webkit" myopia. Understandably browsers supporting HTML5 are cooler from developer perspective but many examples given did not work or broke when another browser was used (Firefox, IE). This is poor for any platform claiming universal compatibility. Hopefully this will improve next year.


Cheers,
-B

Thursday, September 30, 2010

CF: ORM EntityDelete without EntityLoad

I must admit I am not a fan of the EntityDelete() function. Its inability to handle multiple records always nagged me. I know I can allways go back to CFQUERY or use ormexecutequery(). But what nagged me the most appeared to be the need to do an EntityLoad before I could remove the entity/record. This could potentially introduce unneeded database reads and latency.
e.g.:
myBook = EntityLoad("Book", 100, true);
EntityDelete(myBook);


Well it turnes out that the use of EntityLoad is not required. A colleague suggested I try the following instead which would eliminate the load operation, and since I thought that was pretty neat I am sharing ;o)

mybook = new Book();
mybook.setBOOKID(100);
EntityDelete(mybook);

In this fashion, you are creating the object reference in memory and guaranteeing that there is only one DB interaction at DELETE.

Cheers,
Bilal

Sunday, July 25, 2010

VS2010: Visual Studio 2010 - finding web reference option when working with Windows Forms Applications

Something I ran into today made me do a double take. This could have originated from the initial configuration choice I made when setting up Visual Studio 2010 or the tool is trying to be so smart it starts to get confusing..


However it happened, it does seem to make things more difficult when trying to create windows form applications. In particular, if you want to use a web-reference in your regular windows application the number of clicks has increased and discoverability has decreased.

Adding web-references to consume web services in ASP.NET application is not impacted by this change. In particular the context sensitive links to add web-reference are gone when I am in the Solution Explorer working on a Windows Form Application.






Instead the only thing you can seemingly do is to add a service reference. Though you can start here, web services that are registered through this channel do not behave at all like the previous releases of Visual Studio. Thus, beware, this is not what you want to do if you want to consume a regular web service, especially ones that are not created with VS to begin with. To get to the plain Jane adding of a web service you have to walk through some additional steps.

A) Select the "Add Service Reference..." option, then, click on the "Advanced..." button.





B) Click on the "Add Web Service" button from the advanced screen:




Allright that should do it to bring you back into the old web service ways.

Cheers,

B

Saturday, July 17, 2010

CF: The varExists() function -- Expanding IsDefined() to work with regular array and associative array notations.

Many times while working in ColdFusion code I am encountering the simple need to check for the existence of an index in an array, e.g. myArray[3]. While other languages may have had easier checks on this, in Adobe ColdFusion, I unfortunately, have to work around this scenario with many lines of code or different functions to call. Thus, I am able to construct fully well formed variable references and use them, but cannot check their validity in a simple fashion.

For example, I can't do a simple call to a universal function such as IsDefined("myVar[3]"). In this simple scenario we could have used ArrayIsDefined(), however, the scenarios I normally deal with are not so simple. In my scenarios I am not sure about whether "myVar" is an array in the first place or whether the index is numeric. E.g. I may need to check myVar[checkIndex]; this maybe a strucure with an associative array notation which takes me back to square one. Along these lines, multi-dimensional arrays such as myArray[3][4] are equally unqualified for ArrayIsDefined().

Similarly associative array notations that can be used with structures, e.g. myStruct["testNode"], equally do poorly on these checks and could require some sort of special checking and more lines of code.

How about a combination of things:
TestStruct.Animals['species'][1]['counts'][2]

All of these scenarios go beyond the ability of IsDefined() or other functions and cause more code to be written. Maybe this would be an opportunity to expand in future version of ColdFusion but for now we're stuck or are we? (yeah, rhetorical question this one).

I made this a test project and developed an alternative function, varExists(), to IsDefined(); it may not be usable in all scenarios but will come in handy in coding.
The sample implementation can be downloaded here (varExists.zip (3KB)).

The first objective was just to be able to handle the complex notation scenarios that commonly fail under IsDefined().

e.g.:
varExists("TestStruct.Animals['species'][1]['counts'][2]") should operate without a hitch on complex variable notations. While at the same time maintaining full backward compatibility with IsDefined(). So you should be able to do things like this varExists(varName), varExists should check for the existince of the content referenced by the content of varName, e.g. a string such as "TestStruct.myArray[2][1]".

But, why stop there, the next thing that I commonly do once I check for the existence of a variable is to retrieve its value for some sort of operation, so I added this option as second argument. Thus, varExists will automatically return the value referenced as part of its operation if "True" is passed as second argument, e.g. varExists("myUserArray[33]",true). This would return the UserName at array index position 33.

Another common task I perform when the value is not known or "undefined" is to assume a default value. Thus, I added this as third parameter. When a third parameter is supplied it will be returned, when the actual variable reference is undefined.
For example:
varExists("myUserArray[33]",true,"John Doe")
would return "John Doe" if the array index 33 is not populated for some reason.

The example code has the test array and unit tests with sample scenarios. The hope is that eventually the ColdFusion language can accommodate these type of operations natively.

Happy experimenting.

Cheers,

B.

Addition:

The Railo CFML engine does not exhibit the flaw outlined in this article. Thus, if you use Railo, you probably will not encounter scenarios in which you can construct a valid variable reference but cannot check for its existence. The IsDefined() function works as expected, however, if you want the expanded functionality of retrieving variable values etc. you would still need to use the varExists() User Defined Function (UDF) provided here.

Best,

B.