Angular applications are, typically, single page applications.
So when you move around in an Angular application and an area (or areas) of the screen changes, you're said to be
moving from one "state" to another. To simplify handling these states you can utilize the very powerful Angular-UI Router. From the GitHub site:

AngularUI Router is a routing framework for AngularJS, which allows you to organize the parts of your interface
into a state machine. Unlike the $route service in the Angular ngRoute module, which is organized around URL routes,
UI-Router is organized around states, which may optionally have routes, as well as other behavior, attached.

Yes, Angular's built in ngRoute module can give you the basics. AngularUI Router, on the other hand, provides the
developer with a simple way of defining very complex state management. Or it seems simple, until...[WHAM!] you hit
the brick wall.

The AngularUI Router is so easy, the documentation is... well, it's "OK". Sometimes you just run into a situation
where the documentation is not clear enough. For instance, what if you're trying to call the same state, but with
new parameters?

"What do you mean, Cutter?" Take the following example. A user is browsing a category in an online store. On the
screen is a layout loaded with inventory of that category. Clicking on an item would bring up the detail of that
item. After the detail of that item there are links to additional items, either related to the original, or of a
similar nature. Seems pretty straightforward, right?

Wrong! (Well, not wrong, but....) It's not always so straightforward.Categories fall under the app, and inventory
falls under a category. This says that we need a nested state approach. To illustrate, let me give you some basic
routing here to kick it off.

The initial state ("store") is the site wrapper (navigation and footer and stuff). The category state would
likely include some lookup of inventory for the category, and lay out that inventory on the page. The item state
might open a modal for that item, with a title and image. It gets an itemid as a param, but for security reasons it
is not in the url. There's also no 'view' associated with the item state, with the onEnter handling any UI changes.

So, what's the problem? Well, the issue is the additional inventory items that display below the item details. If
a user is looking at an item, then chances are they're in the "store.category.item" state. The additional inventory
links on this view would also link to the "store.category.item" state, with the difference being the itemid being
passed. If the param were in the URL it might be different, but since it's intentionally being hidden the URL does
not change. So a user clicking on a link with a ui-sref (for the same state they are currently in) just chokes.
The same happens if your controller or service tries to call $state.go('same.state', params). You can add a reload
option to your $state.go() call, but it will reload all the way up the parent state as well.

The requirement ran as followed:

Want to reload a child state, without reloading the parent

Want to change the parameters of that state

The (to be loaded) child state has no UI of it's own, no template, and no URL params

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org<a ui-sref="store.category.item({itemid: item.id})">{{item.name}}</a>1<a ui-sref="store.category.item({itemid: item.id})">{{item.name}}</a>

It was really frustrating to find my click wasn't working, and took even longer to figure out it was because I was
already in the "store.category.item" state. So then I tried something like this:

But, of course, that would reload the entire state tree, parents on down. This was unacceptable. Finally, I found
that I couldn't use the standard ui-sref bits to do what I needed to do. So, I ripped that out, and replaced
it with an ngClick method in my controller:

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org<a ng-click="ctrl.goToItem(item.id)">{{item.name}}</a>1<a ng-click="ctrl.goToItem(item.id)">{{item.name}}</a>

Closer. I could set a break point and see that it was trying, at least. But still not right yet. I scoured the
Guide for information, and then went
looking through the API
Reference, before finally stumbling upon $state.transitionTo().

The $state.transitionTo() method is used by $state.go(), under the hood. But, if you don't read
through the documentation, it is easy to miss a little nugget in the description of the reload option:

reload (v0.2.5) - {boolean=false|string=|object=}, If true will force transition even if the state or params
have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd use this when
you want to force a reload when everything is the same, including search params. if String, then will reload
the state with the name given in reload, and any children. if Object, then a stateObj is expected, will reload
the state found in stateObj, and any children.

What??? That's not what the go() method's reload option does? In the go() method, the reload
option is strictly a boolean. This says that, if I supply it with a string of the state to reload, that it would
reload from that state down through it's children (if it were a parent of the one I was calling). By setting it
to the same state I was trying to call, I ensured that it only reloads my item state, inheriting
data from parent states. So, I tried it out...

Success! I could merrily bounce around among my inventory, reloading only the named state as I went. Glorious
jubilation all around as the band played on (OK, going a little overboard here). Point is, it worked.

The AngularUI Router is immensely powerful, and can truly provide some complex (yet elegant) state management
within your application. I highly recommend reading over the guide to see what might be available to you.

This entry was posted on November 17, 2015 at 9:41 AM and has received 2420 views. There are currently 0 comments.
Print this entry.

I'm really loving the changes introduced in ES2015 (otherwise known as ES6 or
the new JavaScript). At work we've transitioned to working in ES2015, and discovering
the differences has been both fun and challenging, especially when it comes to
changes in how variables are scoped. But we'll save some of that for another
day, and talk for a moment about passing data around in an Angular application,
and how you can have some fun with ES2015 classes.

In Angular, a Controller can have Services as dependencies. Services are singleton
in nature, so a Service shared among multiple components can be used to "share"
data, to a degree. First, let's create a simple controller with a few dependencies
and a custom variable we want to track both within the controller, and among
other bits of the app.

First, some might ask "Cutter, why didn't you just pass that variable into the
method?" Well, sometimes you just can't. Others might ask "Isn't it passed by
reference?" Scoping changes have adjusted how this works as well. Changing the
variable in the service won't automatically update your controller variable. We'll
talk more about that in a moment. Still other's might ask "What is 'let'?"
That's a conversation about the differences in variable assignment in ES2015, and
is really a discussion for another day. Ultimately I used let because
I need the variable to be mutable.

But, to explain what I'm doing here, the add() method takes an order.
What you can see of the method, it gets our custom variable and applies it to
a local variable for easy reference. We update it with data from the order
that was passed in. We then reset the Service property with the updated data.

OK, but that syntax with the Service property is odd, coming off of ES5. How
does that work? Well, ES2015 classes allow for implicit getters and setters of
properties. Consider the following:

In the past, to access and change a property of an object would have required
us to write some kind of getter or setter method. In this example, you can
simply access and change the property directly through dot notation. But let's
say you want to do something a bit more complex. There may be some bit of pre-
or post-process you want to do, either when setting or getting the variable.
For this, ES2015 classes allow you to define custom getters and setters:

Where this could come in handy is in that inter-app communication. A Controller
can call methods on the Service, to set values and stuff, but the Service can't
automatically pass data back to the Controller based on actions from other items
accessing the Service (like our orderService interaction above). But, in Angular,
we can use event handling and binding in this instance. First, let's put a listener
on our controller:

Yes, the arrow function is a different concept for most front-end-only developers. I'm
not going in depth on that here, but you can find plenty of info out there about them. The
gist here is that if the crazyUpdated event is cast it will pass a new
value, that we then use to update the Controller variable. This also tells us
that myCrazyVar will always be changed from outside of the Controller.
Now let's do some magic to make sure that event gets cast. In our dataService:

So we use our custom property setter. When the value is changed, it automatically
broadcasts that change. The Controller then picks up that change, and applies it
to it's own internal variable.

So, what have we learned here? Well, first there's some samples on using ES2015
classes as Controllers and Services within Angular. Simple examples, but there
you go. Next, we talked about class property getters and setters, both implicit
(no need to define, they just work), and explicit. Our explicit example shows
where you can apply some additional logic during those processes. This may not
be the greatest example, but it shows you that you can do stuff. Probably the
greatest usages here will be in data validation, or in splitting concatenated
data (like a full name to first and last, for example).

Using those ES6 classes in your app is a matter of importing the
classes into your app:

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.orgimport {MyController} from './MyController'; import {DataService} from './DataService'; import {OrderService} from './OrderService';

So, it's still all new to me, these changes to scope and classes and the like.
But it's fun, and powerful, and has a ton of possibilities. If I screwed something
up just let me know. All feedback is welcome.

This entry was posted on November 16, 2015 at 10:48 AM and has received 8199 views. There are currently 0 comments.
Print this entry.

So, you've made the jump to writing tests for your code. You've
discovered the value of TDD, and even integrated it into your CI process.
Awesome! Well, until your tests fail. Then you bang your head against
your desk, trying to figure out how to test "this" scenario, and get totally
frustrated by the lack of information. Makes you want to quit writing code
and start driving the little cart around the driving range that picks up the
golf balls.

We've all been there. This morning in fact. Don't give up, you'll figure
it out soon enough. For example, you're trying to test a new method in your
code. Within this new method you're referencing an object that's on the
global scope. But, of course, you get a 'fail' every time, because your
test doesn't know what that object is.

The answer is to mock the object. But how do you mock an object on the
global scope? Really, it's easier than you might think. Just decorate your
window.

Within your root 'describe' block, you probably have a test global
'beforeEach()' where you're mocking your module. Here, you can create a
'decorator' for Angular's '$window', and attach a mock of your object.

When the test is run, and the 'myMethod()' function is called on your
controller, which internally calls 'foo.bar()', the test will see that and
resolve it with the 'andReturn()' value you supplied.

This is invaluable when you're writing tests for those areas of your app
where you're calling the Google API's, or some script that dynamically
embeds a video player or something. Your test isn't worried about their
code (that's something else all together). Your test is about knowing that
your code does what it needs to do.

As they say, "there's usually more than one way to skin a cat" (I'm really
going to have to find out where that coloquial nugget came from), so if you know of
another way to perform the same test scenario, please share.

This entry was posted on August 26, 2015 at 3:54 PM and has received 3631 views. There are currently 0 comments.
Print this entry.

2014 has been an outstanding year for me, in many ways, but perhaps one of the most important things (besides my family) has been continuing to do what I love. I'm passionate about development, and constantly working to learn new things. This is important for any developer, as our world changes so quickly today. New standards, new languages, new frameworks, it's a consistent onslaught of new ideas, and impossible to learn each and every one, but important to get exposure none-the-less.

The early part of the year I was still maintaining a large legacy application. We were in the final stages of migrating some very old pieces of the application into new framework architecture (FW/1) along with a new look (based on Bootstrap 3). When you're working on legacy applications, there are rarely opportunities to dive in to new things, so that project was a nice nudge to explore areas previously untouched. Back in April, though, I took on a new position that had me doing nothing but non-stop new product development. Not only was this a great switch, but the particular tasks I was given had me working with technologies with which I had little or no exposure, and often without a team peer who could mentor me, as many of the technologies were new for the company as well.

Historically, I'm a server-side programmer. But, over the last several years, I've spent a great deal of time honing my client-side skills. I'm no master, by any means, but I've consistently improved my front-end work over that time, and 2014 built upon that considerably as well.

One area I could get some mentoring in was AngularJS. This was a big shift for me, and while I am still learning more and more every day, it has been an exciting change up for me. Angular is extremely powerful and flexible, taking some hard things and making them dead simple (to be fair, it makes some simple things hard too ;) ). Angular is one of those items I wished I had spent more time with a year or so back, because in hind-sight it could have saved me hundreds of hours of work. I'm really looking forward to working more with Angular.

From a software craftsmanship standpoint, I also had to dive in to a slew of technologies to assist in my day-to-day development. I now use Vagrant to spin up my local dev environment, which is a godsend. One quick command line entry, and I'm up and running with a fully configured environment. I went from playing around with NodeJS to working with it day in and day out, writing my own plugins (or tweaking existing ones), and to using (and writing/tweaking) both Grunt and Gulp task runners for various automation and build tasks. To take something as "source" and convert it to "app" with a simple command line entry is the shiznit. How many hours did I waste building my own sprites, and compiling LESS in some app? Now it happens at the touch of a few keys.

Then there are the deep areas that some project might take you. I had to dust off year's old AS3 skills to refactor a Flash based mic recorder. There was some extreme study into cross-browser client-side event handling. Iron.io has a terrific product for queuing up remote service containers for running small, process intensive jobs in concurrency without taxing your application's resources. That lead into studies in Ruby, shell scripting, and Debian package deployment (not in any sort of order), as well as spinning up NodeJS http servers with Express.

Did you know that you could write automated testing of browser behavior by using a headless page renderer like PhantomJS? Load a page, perform some actions, and record your findings, it really is incredibly powerful. It also has some hidden 'issues' to contend with as well, but it's well worth looking into, as the unit testing applications are excellent. Then you might change direction and checkout everything there is to know about Aspect Ratio. It's something you should know more about, when thinking about resizing images or video.

(Did I also mention that I went from Windows to Mac, on my desktop, and Windows to Linux, on my dev server? Best moves I ever made!)

Speaking of video, I got the opportunity to go beyond the basics with ffmpeg's video transcoding. For those unfamiliar with the process, you write a command line entry defining what you want. Basically it's one command with 200+ possible flags in thousands of possible combinations, and no clear documentation, by any one source, on how to get exactly what you want (read: a lot of reading and a lot of trial and error).

If that had been all of it, it would have been a lot, but then I really got to have fun, and got to rewrite a Chrome Extension. Now, I had the advantage that we already had an extension, but I was tasked with heavily expanding on it's capabilities, and it's been a blast. Going from something relatively simple to something much more complex is always a challenge, but doing so when you don't fully grasp the tech at hand is even more challenging. Google has created a brilliant triple tier architecture for interfacing the browser 'chrome' with the pages inside them, and developing advanced extensions with injected page applications has a lot of twists and turns along the way. I've learned enough along the way that I'm considering writing a presention on this process for the upcoming conference season.

So, in retrospect, I went from maintaining a large legacy system to doing cutting edge custom development, learning something new each and every day. Awesome! Now, the downside to this sort of process is that you lose valuable productivity time getting through the learning curve. It's difficult to make hard estimates on tasks that no one else has done before, and measuring success is taken in baby steps. But the upside is that you are constantly engaged, constantly motivated, and those skills will eventually translate into better products down the road. Products that won't incur that same learning curve (not to mention the new ideas that can come from exposure to so many different technologies). I can't claim mastery of any of it, yet, but did gain a solid foundation in most of it, and it just makes me hungry for more.

So, if I have one wish for 2015 for you, dear reader, as well as myself, it is only that you continue to learn every day. Maybe not to the levels described above (for I am a bit of a lunatic), but at least take the chance to branch out into one new area of development in the coming year.

This entry was posted on January 1, 2015 at 4:15 AM and has received 3172 views. There are currently 3 comments.
Print this entry.

Due to a donation from Bruce Lomasky (thanks Bruce), I've written a new CFQueryReader for ExtJS 5. CFQueryReader is an Open Source project, available on GitHub, that I began years ago to create a proper reader for parsing Adobe's native ColdFusion query JSON return format into something usable by ExtJS data stores. As ExtJS has changed over the years, I have updated the reader to accommodate new versions. But, I don't do much ExtJS development anymore. It's a great front-end app development framework, but I've changed jobs a few times since co-authoring the first books on the library, and just don't work with the technology on a day to day basis anymore. Bruce had a need, and offered to pay for the development of an updated reader. So I dove back in to the ExtJS pool, to help him fulfill his requirements and put a new reader out there.

ExtJS went through a major rewrite between versions 3 and 4, requiring an entirely new direction. While much is backward compatible, in the move from version 4 to version 5, there were some big changes to ExtJS' data packages. Sencha has always done a good job with creating a rich, dynamic framework for web application development. I have always been impressed with their commitment to improving the product, continuously modernizing the framework, and creating more of a "software craftsmanship" approach to web application development. That said they haven't always done such a great job with ensuring an easy upgrade path for developers. Changes to their data package completely broke some of the use cases of CFQueryReader, requiring some refactoring to accomadate.

And that's OK. Sencha's changes to their data packages are some welcome changes, especially for our little plugin. In all of the past revisions of CFQueryReader, we've extended a base Array Reader class, and written an override method of the core readRecords() method. While this worked, it was really kinda kludgy. What we really needed was a way to transform the incoming data packet prior to the reader really processing the object. With ExtJS, we now have that ability to do just that.

ExtJS 5 introduced a new configuration option for data readers: transform. This new configuration attribute takes a function within which you can manipulate the return data of a store's ajax request prior to the reader actually processing that data. This gives some underlying flexibility that wasn't really there before, especially when using Ext.Direct, but for now you really just need to know the basics.

ColdFusion upper cases object keys when it serializes to JSON. If you are manually creating the structure, there are ways to fix that:

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.orgColdFusionJson = { COLUMNS: ["KEY1","KEY2","DIFFERENTKEY3"], DATA: [ ["some value","this one is cased differently","this one is more different"] ] };1ColdFusionJson = {2 COLUMNS: ["KEY1","KEY2","DIFFERENTKEY3"],3 DATA: [4 ["some value","this one is cased differently","this one is more different"]5 ]6};

When you build your reader configurations, we no longer worry about this casing, as we will do a case insensitive matching of keys during the pre-process:

Have been converted with ColdFusion QueryForGrid (not suggested, but supported)

And, because ColdFusion 11 includes the new "struct" type for the queryFormat parameter (even as an argument of your ajax request), CFQueryReader will properly parse that as well.

And, since we can now process the return prior to ExtJS calling it's internal readRecords() method, CFQueryReader no longer extends Ext.data.reader.ArrayReader as it's base class, but the more appropriate Ext.data.reader.JsonReader instead, allowing for a more native access approach under the hood.

I've made the new plugin available, for now, within the Ext5 branch of the repository. If you have the need, take it for a spin, and let me know if there's anything that might require tweaking.

This entry was posted on December 4, 2014 at 10:53 AM and has received 4240 views. There are currently 6 comments.
Print this entry.

As most of my readers know, I still love ColdFusion. In 15 years of development there are still very few things that I've found that I can't do quickly and easily with CF. That said, ColdFusion isn't always the right tool for the job. I don't mean that ColdFusion can't do the job, only that it's maybe not the best tool. The UI stuff is one great example. The ColdFusion UI stuff was written so that the most novice of developers can spin something up fast. But, anyone who's had to do something a bit more complex quickly finds the limitations behind it's generated UI code. Another is extremely resource intensive processes. Doing image manipulation on one image occasionally isn't such a big deal, but what happens when you have to process several thousand? As powerful as the language constructs are for manipulating these images, the constant conversion of binaries into Java Image Buffer objects, the increasing back and forth within RAM, it begins to bog your server down to the point of a dead crawl.

This image example is just one of many, and when you're writing enterprise level applications you're going to hit these hurdles, and using ColdFusion in these instances is like using a hammer when you need an Xacto blade. This is when you start looking for better options to these processes, that can interoperate with your current ColdFusion services. In looking for just such an option, I was pointed to Iron.io.

Iron.io is a cloud-based set of services that can be run on many of the major clouds. They began with a distributed Message Queueing service (IronMQ) built for handling critical messaging needs for distributed cloud applications. Building upon their queueing abilities, they also created IronWorkers. IronWorkers are async processing task queues. They allow you to define what your process environment needs to look like, your task script to process, and then you can queue up tasks which can asynchronously run in their own independent container environments. Once queued, IronWorker with run X number of tasks asynchronously (X being dependent on the plan level you choose). Each task runs within it's own sandbox, with it's own independent RAM and processor allocation, so that one running process does not affect another. As tasks complete their sandbox is torn down, the queue continues to spin up the remaining tasks on demand, until the task queue is done.

The ease with which they've developed this service is amazing. Your ".worker" file defines your environment. Each instance is a headles Ubuntu system. You can select from a number of "runtime" setups, allowing you to work in the language that you're most comfortable with (Node, Ruby, PHP, Java, etc), as well as picking a specific "stack" if you want to mix and match the setup a bit. Each instance also already comes preloaded with several common Linux Packages (ImageMagick, cURL, SoX, etc). Within your ".worker" file, any additional files, folders, etc that you require can also be defined, including .deb packages.

Once your worker is defined, assets gathered, scripts written, etc., you then create your worker from a simple command line call. Once the "build" is complete, your new task service is ready to be called. This can be done via command line or (perhaps more commonly) via an http call. You can even define a webhook for your worker that can kick off your tasks from Git or elsewhere. You can pass variables to your task as part of it's "payload". This is just a simple HTTP Post, passing in name/value pairs that can be used within your process script. The "payload" is limited to 64k in size, so any files you may need on the fly (such as images to process) should be retrieved from within your process, most likely from somewhere like S3. Your process does it's thing, your script sends a command to exit the process (process.exit()) and it's done, spinning up the next task in the queue.

There really is a lot more to it. You can get as simple or as complex as you are capable of writing. IronWorkers are extremely powerful, and scale beautifully. After several weeks working on multiple processes, I can also say that their support is exceptional. They have HipChat channels setup to assist people, and they've been extremely responsive and helpful. They also maintain sample repositories of many common tasks, in a variety of languages, to help you get started while working in whichever environment you're most comfortable with.

This entry was posted on November 3, 2014 at 12:55 PM and has received 3502 views. There are currently 0 comments.
Print this entry.

Well, it's that time again. Later this week is the second annual ColdFusion Summit, put on by Adobe. Last year, just prior to the summit, I posed the question What's Wrong With ColdFusion. The feedback was immediate, and intense, with many people weighing in with their thoughts on what could be done to progress ColdFusion, both as a platform and a language.

Unfortunately, last year I wasn't able to attend the summit, and development of the ColdFusion 11 server was nearly complete, so most of that feedback had zero impact on the new release. While their were many advancements in security and JSON processing, some of the other introductions were seemingly underwhelming, or even unwanted, to many long time CF developers.

Now, to be fair to Adobe, and the ColdFusion product development team, they do have a responsibility to cater to their paying customers. Developers are rarely the ones buying the server itself, and the money handlers buying the server licenses rarely have enough real understanding of the development process to truly provide reasonable feedback when asked "What do we do next?"

Past issues aside, the ColdFusion product team is beginning to explore what they will do with the next version of the ColdFusion server, so now is a good time to begin the discussion again as to what Adobe might do the next time around. It is a delicate balance, so our feedback to the team needs to be positive, constructive, and backed by hard arguments to support our requests.

ColdFusion has been known, since the very beginning, for making the hard things easy, with it's first inroads being in the are of data connectivity. ColdFusion makes it extremely easy to connect with a wide range of datasources. This was probably the first true task of CFML (originally called DBML). It's meeting this type of root level need that ColdFusion might need to focus on going forward.

There were a number of core concepts that came out of last year's discussion:

Script Language Overhaul

Command Line Interface

Package Manager

Modular Architecture

Support for NoSQL Databases

Application Profiling

There are some great suggestions here, and Rupesh actually had included these in his final slide of the cf.Objective keynote presentations as possible items of inclusion in the next version of the ColdFusion server. I, personally, say to Adobe that it is important to review the past year to help define the focus for the future. It is important for the product team to not waste time on solutions that are already available, or that developers can already do themselves with a little study. In that vein, the CLI and Package Manager may not be areas for Adobe to spend time on, since we now have CommandBox available to us. Focusing on solutions that are already freely available to us seems to be a waste of time and resources, unless you intend to go above and beyond any available solution. A key question to ask, in this type of evaluation, is not only "is this already available?" but also "does this truly fit the purpose, enhancement, and growth of our product?"

Modular Architecture

So, what sort of things can Adobe do? Well, the Modular Architecture concept has multiple levels of benefit, not only for developers but for Adobe as well. By creating a "core" build of ColdFusion (db interactivity, includes, custom tags and the like), with "packages" of additional functionality (ORM, CFFORM, CFCLIENT, etc) that could be installed only when required, Abode creates an architecture where developers can customize their environment to the needs of their application. This decreases the overall footprint of the server, removes the "cruft" that might be unnecessary, and expands the licensing options for Adobe as well. I also believe this could significantly improve the cloud options that could be offered for the server as well, which could greatly improve adoption of ColdFusion as a platform.

Image Processing

Image manipulation was a long time coming to ColdFusion, and was a great addition once it finally arrived natively. That said, the current implementation is very process intensive and slow, and support isn't quite what you would expect from a brand like Adobe. It may be time to revisit image processing in ColdFusion, possibly even exploring avenues other than Java for handling these processes, to improve quality and performance.

Server Performance

There is strong evidence pointing to other CFML engines (Railo) as having much better overall server performance. It is difficult to allocate time and resources to something that currently works. But, just because it functions doesn't mean it shouldn't be improved upon. Response time is a critical piece to any application, and Adobe ColdFusion (as a paid and licensed product) should be the best of breed in this category.

Language Overhaul

Again, it's difficult to put time and effort into something that already works. But, the current syntax of script and functions within ColdFusion is a barrier to adoption of the server. This may be one of the biggest, and most asked for, enhancements that Adobe could provide to ColdFusion. Developers, who have traditionally worked in other languages, spend little time evaluating ColdFusion as an option because of the belief that ColdFusion is a second class language. Why would you use ArrayAppend() when every other language uses array.push()? Many objects do provide Java level object access, but many of these are undocumented, or aren't displayed in the documentation as the first line of how something should be done. While ColdFusion must support the current language constructs for some time to come, it really is time to make a more ECMAScript compliant form of script for ColdFusion. Or, at minimum, something much more uniform and familiar.

What Next?

So, with the summit starting later this week, I pose the question again "How can ColdFusion be better?" What would you like to see Adobe focus on for the next version of the ColdFusion server? And why? How? To what purpose? What do you think are areas where Adobe should absolutely steer clear of? It is important that we provide our feedback now, early in this process, and that we do so in a positive and constructive manor.

I will bring any comments given here back to the ColdFusion product team at the summit later this week (yes, I'm presenting this year). I encourage everyone who is going to the summit to voice your opinions directly to the product team as well. I look forward to hearing everyone else's input on this.

This entry was posted on October 13, 2014 at 6:15 PM and has received 44359 views. There are currently 10 comments.
Print this entry.

A while back I was playing around with Ghost, a blogging platform written for NodeJS. Crazy simple to setup, one of the nuggets that I found during the 5 min install was a reference to Mailgun.

Mailgun is advertised as "The Email Service For Developers", allowing you to send 10,000 emails for free every month. It has a nice API, and is very simple to use. A common problem that many ColdFusion developers have, when writing an app, is having access to an SMTP server solely for development practices. You can setup a local server, use some Windows SMTP service, or traffic mail through your personal accounts, but it really is better to have a sandbox that's a bit more separated, for security, sanity, and other reasons. ColdFusion 10+ have a built in SpoolMail utility (based loosely on Ray's project), but sometimes you just need to see the real output in a mail client instead of the browser.

Setting up an account was easy on Mailgun. Right from the homepage was a link to the free sign up page. Once the account was created I was given a Mailgun Subdomain. This is my sandbox to play in, so I clicked on the domain name, for the domain admin page, then clicked on the "Manage SMTP Credentials" link on the "Default SMTP Login" line item. From this page I was able to create a new sender (you can use the default if you wish, but sometimes I'll setup separate addresses for specific tracking purposes).

The final stage is to put the settings in the ColdFusion Administrator. From the mail settings area I entered my new "sender" address as my SMTP server username, the password that I created with the account, set the SMTP server address to "smtp.mailgun.org", and changed the SMTP port to 587. (The default port 25 will NOT work, but 587 with no other settings changes will work fine.)

Now I can send mail with ColdFusion from my dev environment without having to load my own SMTP server or subbing out my personal addresses.

This entry was posted on September 21, 2014 at 9:48 PM and has received 44228 views. There are currently 3 comments.
Print this entry.

So, recently I've been playing with PhantomJS. For those who are unfamiliar, PhantomJS is a headless webkit engine, that you can use to perform automated testing, take screenshots, and dozens of other things.

Phantom is still fairly new, and this has been a learning experience. My first trials were using the phantomjs-node module for NodeJS. I soon discovered (with some assist) that this bridge has some performance issues of it's own, and had to move to the command line.

When working with PhantomJS in this fashion, you write a script (in JavaScript), and pass it to PhantomJS along with any necessary arguments. I call this command line from NodeJS directly, but you can do so in Terminal or the cmd shell if you want.

Here was the catch. I had some math in my PhantomJS script. Not even complex math, really, just some basic equations converting milliseconds to seconds and rounding it off:

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.orgvar system = require('system'), args = system.args, pageArgs = { elapsedTime: args[6] // this value is in the command line as 13762 };

Now, you and I know the answer is 14, but PhantomJS didn't seem to like that:

The answer is not 0

If I hard code the numeric value of elapsedTime (13762) into that statement then the math parses correctly. It appears that performing math on the values passed in causes the issue. I can change up the equation by adding 250 milliseconds:

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.orgvar totalTime = Math.round((pageArgs.elapsedTime+250)/1000);1var totalTime = Math.round((pageArgs.elapsedTime+250)/1000);

But PhantomJS still doesn't like it:

The answer is not 413

Crazy, right? What I found was, if I needed to do any math to set some variables for use in the script, then I needed to do those in my node process, and pass the evaluated values to my PhantomJS script as arguments in the command line.

REVISION NOTE: Further testing shows that the command line arguments will all come across as a "string" type, which may be why these equations were miss firing. Remember to explicitly convert your command line arguments to the necessary data type, to avoid this type of issue.

This entry was posted on September 11, 2014 at 11:21 AM and has received 3071 views. There are currently 0 comments.
Print this entry.

In my newest position I've been learning AngularJS. After diving in for a little over two months now, I'm seriously loving it, and wondering why I didn't seriously look at it much sooner.

One of the things it has taken a bit to get used to is that Angular does some things differently. I love Bootstrap but, like all other plugins, Angular's MVC approach has you do things "the Angular way", which can take a bit to break old habits. Luckily for us there are projects like Angular UI to help take the pain out of these sort of things.

One of the very few things that I use jQueryUI for is it's Sortable, Draggable and Droppable plugins. Angular UI has modules for these too. In this example, we're going to use the Sortable plugin for easy Drag n Drop display order management.

Using Drag n Drop for display order management is a fairly standard task. In the old days, we used up and down arrows that would typically be links, firing calls back to the server for database interaction and the refreshing the page for the new order. This was long, tedious, and a horrible user experience. Drag n Drop takes care of that. It allows the user to quickly define the order of things prior to ever sending data back to the server.

This demo isn't going to get into the server side mechanics of any of this, but rather the client-side stuff. First we'll start with the Bootstrap sample template (we'll use the Bootstrap CSS for basic layout stuff in our example). Don't forget to take out the Bootstrap JS file, and we're going to load the jQuery file up at the top ("why" will become clearer later).

A requirement of the Angular UI Sortable plugin is the actual jQueryUI sortable plugin, and it's dependencies. Luckily we can download a really trim file, giving us only what we need. We will insert the JS file in our document head, directly after our jQuery file.

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org<script src="/path/to/file/jquery-ui.min.js"></script>1<script src="/path/to/file/jquery-ui.min.js"></script>

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular.min.js"></script>1<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular.min.js"></script>

And then we need the Angular UI sortable. I haven't found a CDN for this one, so you'll have to install it locally:

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org<script src="/path/to/file/ui-sortable.js"></script>1<script src="/path/to/file/ui-sortable.js"></script>

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org<script src="/path/to/file/sortable-app.js"></script>1<script src="/path/to/file/sortable-app.js"></script>

Basically this says our app is called "sortable", and it has a dependency on "ui.sortable". That part was easy enough, but now we have to associate the app with our display. We do this by modifying our opening html tag:

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org<body class="container" ng-controller="ListController">1<body class="container" ng-controller="ListController">

We created a controller, and associated it with the body of our document. You can assign a controller to any element within your document, but this is a pretty simple example, so we're going simple here.

We need some data. Ordinarily you'd probably pull some data from the server, but for our demo we'll just create an array in our controller. The variable will be within the controller's scope, making it available to the block of our view within the ngController's elements.

OK, I need to slow down a minute. Let's explain some code here. First, I loop over the bands for output. If it's in "view" mode, it shows you the rank, and the name. If it's in "edit" mode, then you see a text box and a button. Lastly, there's a button at the bottom for adding new bands.

There are two methods tied in here. Let's add them both to our controller:

Nothing crazy here. We aren't doing any server-side stuff in this demo, so all we're trying to say here is "create" will put a stub object last in our bands array, while "add" will change a step's mode from "edit" to "view".

You can try that out now, if you want. Clicking on the "Plus" button at the bottom will add a new line for you. Type in a Band Name and then click that line's "Add" button. Each time you hit "Add", the mode changes to "view", and you see the display order followed by the Band name. You can add as many bands as you like, but so far we still can't re-order them, and anyone who knows me knows that as much as I love The Beatles, Jimi is number one in my book.

You'll remember that we already have the Angular UI Sortable plugin available to us. We included the code, and the dependency, now we just need to implement it. On the div that contains our ngRepeat loop directive, just add the directive call for the Angular UI Sortable:

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org<div ui-sortable ng-model="bands" class="container-fluid">1<div ui-sortable ng-model="bands" class="container-fluid">

This adds the directive to the container, as well as defining the model involved. ngModel is critical here, or it won't work. If you reload your page right now, you'll find that you can Drag n Drop rows backwards and forwards with ease. But you're not done. Just for grins, hit your "Plus" button for a form row, then try to drag it. It's not easy to grab it, but it can be done. Suddenly you're trying to re-order stuff that isn't ready for re-order!

This is easily bypassed, by adding some configuration to your sortable. The jQueryUI Sortable has it's own API and configuration options, and you can easily apply them to your Angular UI Sortable as well. First, create a configuration object in your controller. We don't need much, just something that identifies what our drag handles are (if there's no handle, it can't be dragged):

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org<div ui-sortable="sortConfig" ng-model="bands" class="container-fluid">1<div ui-sortable="sortConfig" ng-model="bands" class="container-fluid">

Now, if you reload and try it again, you'll see that you can no longer Drag n Drop the edit rows.

But, as you continue to drag items around, you'll notice that your display order column of data is way out of wack after a bit. The order should still be "1, 2, 3, etc", but now it's just a jumble. You know that the output is tied to your model, by accessing the band.rank, so as items get dragged around the rank needs to get updated. This can easily be done by watching the bands variable in the controller. We can set a method that says "when this changes, update it":

The $watch function allows you to set model listeners. Here we are looking for any change to the bands array in the $scope. Since bands is a complex data type we include the "true" to match objectEquality, meaning it will watch it "deeply", for any change, and fire when it changes. We're looping every item in the array, and resetting the rank according to it's new position in the array. The rank may never have changed (each time a new row is added this will also fire), but the overhead is pretty minimal, and it's a simple way to ensure the display order is always right.

That's it. Sample Code can be pulled from the download link. If you have questions, comments, or war stories, just hit me with a comment below.