Check out our new training course on AngularJS for Flex Developers

My Road to a SurfaceBook

You probably know Microsoft introduced the Surface Book on October 6th. It is a well designed, and powerful, Windows laptop. My current laptop has developed an annoying hum so a getting a new one seemed to make sense. I decided to splurge and on October 7th and placed a pre-order. This is the formal complaint letter I filed with Microsoft's Executive Escalation team; documenting my horrible pre-order experience.

My Formal Complaint

October 29th, 2015:

My name is Jeffry Houser and I wish to file a formal complaint about Microsoft's handling of my Surface Book pre-order.

As you know, Microsoft announced the Surface Book on October 6th. I was very excited about getting a powerful well engineered Windows Laptop and decided I had to have one.

What follows contains the full details of my pre-order experience problems including order number, case numbers, and the names of support people I spoke with. I hope you'll excuse if me I have incorrect names on the list; as my notes are imperfect, and my phone connection to the support personnel was never crystal clear.

On October 7th: I placed a pre-order for an i7 512GB with 16GB of RAM and a Surface Dock.

On October 19th: Microsoft tried to charge my American Express card and American Express triggered a fraud warning, declining the transaction. I got a phone call from American Express and immediately approved the charge. American Express requested I have Microsoft do a re-authorization on the card and they would approve it. I also received an email from the Microsoft Store asking me to update my payment information.

I tried to re-run the charge on the Microsoft Store site and it was declined. I was notified I only had three remaining chances to fix this issue.

I tried to enter my credit card details as a new card and it was declined because the card was already on file. I tried to re-run the charge on the Microsoft store site a second time with the existing credit card profile and it was declined. I was notified I only had 2 remaining chances to fix this issue.

I called Microsoft around 3pm and spoke to "Roan" who told me a lot of people were having the same problem. Microsoft was working on it. I should wait a few hours to try again.

Around 6pm I tried to run the charge on the Microsoft site a third time and it failed, letting me know I only had a single opportunity to fix the issue remaining.

Around 6:30pm I got on the phone with American Express. They informed me that no additional charge attempts were made against my card and they did not reject it. With American Express on the phone, insisting the charge should go through, I submitted my last attempt through the Microsoft Store and the order was cancelled. Before getting off the phone with American Express, I had them verify that no charge was attempted or declined on their end.

After getting off the phone with American Express, I called the Microsoft Store immediately. I spoke to "Christie". She assured me that the order was not cancelled and that it was just a problem with the Microsoft Store system and the cancellation email was erroneous. She promised me a call back within 24 hours.

On October 20th: I did not get a phone call back within the 24 hour time frame. I called the Microsoft Store around 9:30pm. I was told they were still waiting for an update from a high level support team and promised a call back in 24-48 hours.

Around 10:30pm I received a call from Gloria from Microsoft Store Support. She created a new order for me and promised that my original ship date of October 26th would be honored.

On October 21st: I noticed that the ship date on the second order for the Surface Book listed 6-7 weeks which is very different than what I was promised verbally. I called Microsoft Store and was assured that the email was erroneous and I would still receive the product on the 26th.

On October 22nd: Microsoft called me to cancel the 2nd order and place a new one. I spoke to two support technicians in two separate calls. Both promised I would get the product by the original promised ship date. The Surface Dock on the second order was kept active while the Surface Book on the second order was cancelled.

In retrospect, I am unclear why this was required.

On October 26th: I called Microsoft Store Support around 8:00am to get a tracking number for the Surface Book. The Microsoft Store could give me no information. My Surface Dock was received on this day, but there is no sign of my Surface Book.

On October 27th: I received an email to let me know there was no update on shipping dates.

On October 28th: I received an email to apologize for the delay.

On October 29th: I called Microsoft. This time I called the number in the October 28th email (1-800-642-7676) instead of the phone number in the Order Emails (1-877-696-7786). On the first call, I got disconnected immediately. I assume this was an honest mistake.

I called the number again spoke to someone who asked a lot of my information. In my frustration, I used some inappropriate language. I should not have let my emotions get the better of me, a feel remorse for my verbal slip. I was transferred to the Microsoft Store support team.

I spoke to "Kemp". He said there was a chance my order may get delivered up today, or that it may show up in 6-7 weeks. I pushed for a specific delivery date and asked to speak to a supervisor. He put me on hold and eventually came back to tell me Monday November 9th. I asked once again to speak to a supervisor. After being put on hold, Eugene came on the line. Eugene offered me a $50 discount off my order and promised me a delivery date of November 2nd. During this single call I was given 4 different delivery windows. Given past delivery promises, why would I have any faith that any of them are correct?

At this point, I decided it was time to submit a formal complaint. I've had six different support reps promise me that my order will ship by the 26th; yet here it is four days past that and I'm getting a different story every time I talk to someone.

You can watch a full 30 minute edit of the support calls from before October 26th. You can also watch, a shorter compilation of your Microsoft Store Reps promising me the original ship date will be honored.

Your Microsoft Store staff has always been polite and professional, but ineffective.

This experience has soured my enthusiasm for the Surface Book. As long-time Microsoft Customer, and a small business owner who makes much of his living developing software with Microsoft technologies, I am left with a sour taste in my mouth. I'm no longer asking myself "When will the Surface Book ship?" I've started asking myself "What can Microsoft due to keep me as a customer?"

Can you help restore my faith in Microsoft?

The Aftermath

10/29/2015: Justin H from Microsoft Global Escalation Services emails me in response to my request to file a complaint and tells me he sees nothing wrong with the order. This was in response to me calling Redmond and asking to file a formal complaint, but before I actually could file the formal complaint. The letter above was sent shortly thereafter.

10/30/2015: I walk into a Microsoft Store and buy a SurfaceBook i7 off the shelf. They had a pre-order that wasn't picked up. Now; I have the machine part by coincidence and part by luck.

10/30/2015: Justin H emails me to tell me that the i7s are not shipping until 11-20 and the dates I was given were wrong all around. It turns out either Justin or his warehouse fulfillment team is confusing the Surface Pro 4 i7 with the SurfaceBook i7. I'm not sure if this mixup was an accident or something done just to try to satiate an upset customer.

I email back to have Justin cancel my existing order. He also offers me a partial refund of--roughly--10% of the purchase price. I accept.

10/31/2015: I speak to Justin H on the phone and he apologize for all the problems and promises me the refund. He is going to close the ticket I opened with him. IF there are any problems with the refund or the computer, I should email back and it will reopen the ticket.

So, here we go:

I'm fairly happy with the unit and hope to write a formal review at some future point. I don't think I'll ever be pre-ordering anything from the Microsoft Store web site again.

Why are my AngularJS Directive’s attributes undefined?

Almost every time I create an AngularJS directive, I have trouble passing in values to it. I'm writing this article to remind me of my mistakes. Perhaps you are running into the same issues. If so, I hope this helps.

Create a Directive with Problem 1: Case Sensitivity

First, let's create the directive:


<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js"></script>
<script>
angular.module('directiveApp',[]).directive(dciTestdirectivecs,function(){
return {
restrict: 'AE',
template : "<b>Some Value</b>: {{someValue}}<br/><br/>",
scope : {
someArg : "="
},
controller : function($scope){
$scope.someValue = $scope.someArg;
}
}
});
</script>

First, load in the angular framework. Then create a module specifically for the directive. I named this module directiveApp. The directive is created as part of the module, named dciTestdirectivecs. I defined the module's template in-line. The sole purpose of this directive is to display the value that we pass into it. A scope is defined to give the directive an isolated scope. A single argument is passed into it--someArg.

The directive's controller saves the $scope argument, someArg, into the $scope value someValue. The $scope argument, someValue is output as part of the template.

Let's write some more code to turn this into a runnable application.

First, add a module as part of the script tag:


angular.module('directiveArgumentTest',['directiveApp'])

Then in the main HTML of your page, attach the module:


<body ng-app="directiveArgumentTest">

And use the directive:


<dci-TestdirectiveCS someArg="something"></dci-TestdirectiveCS>

So, if all went well, when we load the app, we should see the directive look something like this:

Some Value: something

But, that isn't what happens. Here is a screenshot from the Chrome debugger:

The $scope.someArg is undefined. Why is that?

The reason is because directive scope attributes must be defined all in lower case. My desire to make use of 'standard' variable naming conventions killed the attribute.

Create a Directive with Problem 2: Simple Values and Inheritance

Let's fix that issue and go onto our second problem:


angular.module('directiveApp').directive('dciTestdirectivesimplevalue',function(){
return {
restrict: 'AE',
template : "<b>Some Value</b>: {{someValue}}<br/><br/>",
scope : {
somearg : "="
},
controller : function($scope){
$scope.someValue = $scope.somearg;
}
}
});

This directive puts the scope attribute properly in all lowercase. Use it like this:


<dci-TestdirectiveSimpleValue someArg="something"></dci-TestdirectiveSimpleValue>

Now when the controller function is executed the somearg should have the value something, correct? Let's see:

Unfortunately, the issue is still not fixed. This is related to how JavaScript handles inheritance and how Angular creates directive instances. Objects are inherited, but simple values are not. This is why many professional grade directives, such as ngGrid, have you pass in options as part of an options object.

Create a Working Directive

Now that we got those two problems out of the way, here is the proper version:


angular.module('directiveApp').directive('dciTestdirectivecorrect',function(){
return {
restrict: 'AE',
template : "<b>Some Value</b>: {{someValue}}<br/><br/>",
scope : {
somearg : "="
},
controller : function($scope){
$scope.someValue = $scope.somearg.value;
}
}
});

The somearg is defined all in lowercase. When we access that value in the controller, we introspect it to get a property on the somearg object. You can use this directive like this:


<dci-TestdirectiveCorrect someArg="{value:'something'}"></dci-TestdirectiveCorrect>

The someArg attribute creates an object with an attribute named value. Run the code, and you'll see you can now properly introspect the somearg object to get at its properties:

Run this in a browser and you'll something like this:

Play with this code here.

Final Thoughts

In summary, if you are having issues with undefined attributes of an Angular directive, here are two things to check:

  • Make sure the directive attribute is defined in all lowercase.
  • Make sure simple values are wrapped in objects.

I've made both mistakes more than I care to admit.

Sign up for DotComIt's Monthly Technical Newsletter

Why would I use AngularJS's 'Controller As' syntax?

I recently found myself in a social media conversation about the difference between AngularJS and $scope variables. I was told that the "controller as" syntax helps achieve larger code separation between the view and controller than using the $scope. I don't agree with that assessment, but decided to look deeper into the approach. This post contains my conclusions.

What is controller as?

The Angular "controller as" syntax is a way to alias the controller. The view code can reference the controller directly through the alias. It is intended as an alternative to the $scope and was introduced in AngularJS 1.2.

Using the $scope

Before I show a sample of using controller as; I want to show a simple example of using $scope. In my experience the $scope approach is more common.


<html lang="en">
<head>
<title>Scope Sample</title>
</head>
<body ng-app="scopeSample">
<div ng-controller="scopeCTRL">
{{someValue}}
</div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js"></script>
<script>
angular.module('scopeSample',[]).controller('scopeCTRL',['$scope',function($scope){
$scope.someValue = "foo";
}])
</script>
</body>
</html>

The angular framework is imported with the script tag. Our own code creates an angular module named scopeSample. A controller is created as part of that module named scopeCTRL. A single scope variable, someValue, is created inside the controller. In the view code, the scopeSample module is associated with the body tag and the ngApp attribute. The scopeCTRL controller is put on a div with the ngController attribute. Inside the controller the scope value is output.

This is the simplest of AngularJS applications. Play with it here.

Using Controller As

Let's rewrite the previous sample to use the controller as syntax:


<html lang="en">
<head>
<title>Controller As Sample</title>
</head>
<body ng-app="controllerAsSample">
<div ng-controller="controllerAsCTRL as ctrl">
{{ctrl.someValue}}
</div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js"></script>
<script>
angular.module('controllerAsSample',[]).controller('controllerAsCTRL',[function(){
this.someValue = "foo";
}])
</script>
</body>
</html>

The angular framework is imported with the script tag. Then an Angular module is created named controllerAsSample. A controller is created on this module named controllerAsCTRL. No scope variable is passed into the controller function. Instead a variable named someValue is created as part of the 'this' object. This this object refers to the controller function; and the someValue is created as a property on that object.

The view code resides above the script code in the HTML page. The controllerAsSample module is attached to the body tag using the ngApp attribute. Inside that is a div which defines the controller. Let's take a closer look at the controller syntax:


<div ng-controller="controllerAsCTRL as ctrl">

In this code, we are defining the controller as something else. This creates an alias inside the div where the controller can be accessed as ctrl. The view code accesses the ctrl variable to display the variable named created the controller:


{{ctrl.someValue}}

You can create functions the same way variables as created; similar to how the $scope is created.

Play with the code here!

Is using controller as better than using $scope?

When writing unit tests against a controller, the controller as syntax might offer you one less object to mock. Since the $scope service is not passed to the controller, there is no need to mock it for display purposes. Beyond that I think this is more syntactical sugar than anything.

Some fear that $scope will become a catch all place to dump everything you need, thus becoming an overly bloated object taking out your app's memory and leading to poor coding practices. I can see that as a possibility, so it is something to be careful of. However, I have worked on many apps where I feel we have not turned the $scope into a bloated dumping place for all things view related.

Some features, such as watches and broadcasts must be implemented on the $scope service and cannot be triggered using the controller as syntax.

Overall, I remain unconvinced one approach is better than the other. It seems like two separate approaches to the reach same end point.

Additional Reading

John Papa has a great post about how he uses the controller as syntax. Near the end of his post he agrees that this is syntactical sugar and both are functional.

I found this post which discusses some possible $scope service issues if you have one controller nested in another. In honesty, I have not yet worked on an app that explicitly nested controllers as part of its architecture. We could say that using an Angular directive nests one controller in another, which is true. However, a directive's code should be encapsulated and not access its parent controller's code.

My conclusion is that either approach can be used to create maintainable code.

Sign up for DotComIt's Monthly Technical Newsletter

What is a filter used for in AngularJS?

An Angular filter is a function used for formatting a value for display purposes. This article will tell you how to create an Angular filter and how to use it. For the purposes of this article, we are going to create a filter that will be used to format a date object for display.

Create the basic application

We're going to need to create a basic HTML Page with an Angular application.


<html lang="en">
<head>
<meta charset="UTF-8">
<title>Filter Tests</title>
</head>
<body ng-app="FilterDemo">
<div ng-controller="FilterDemoController">
Unformatted Date: {{unformattedDate}}<br/>
</div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.js"></script>
<script>
angular.module('FilterDemo', [])
angular.module('FilterDemo', []).controller('FilterDemoController',['$scope',function($scope){
$scope.unformattedDate = new Date();
}]);
</script>
</body>
</html>

The page ties a module to the body tag with the ngApp attribute. The controller is put on a div inside the body with the ngController attribute. In the script section at the bottom, the app and controller are created. A single variable is added to the $scope, named unformattedDate. The default date() constructor is used, creating a date object representing the time the page is execute by the browser. The unformatted date is displayed in the view.

If you're familiar with AngularJS then this should be old hat for you. The rest of this article will focus on modifying this simple application to demonstrate filters.

How can I use a built in Angular Filter?

Angular has a built in filter service which can be used for formatting dates. We will start by using that filter within the view. Inside a view, you would use an Angular Filter with this format:


{{valueToApplyFilterTo | nameOfFilter : Argument1 : Argument2 : Argument3 : and so on}}

The value you want to apply the filter on comes first. It is followed by a pipe character and the name of the filter. After the filter's name, we have a list of arguments that go into the filter function, each one separated by a colon. To apply the date filter to the main HTML file, do this:


Date formatted with in-line Filter: {{unformattedDate | date: 'shortDate'}}<br/>

This tells Angular that we want to run a filter on the unformattedDate value. The filter we want to run is the date filter; and the value we want to pass in is the shortDate.

Try the code out and you should see this:

Play with this code in Plunkr

How do I create an Angular Filter?

In addition to using the built in Angular filters, you can also create your own. For simplicity, we're going to create our own filter for formatting the date:


angular.module('FilterDemo').filter('formatDate',['$filter',
function ($filter){
return function(input) {
return $filter('date')(input, 'shortDate')
}
}
]);

A filter is set up in a very similar manner to a controller, or service. It is created on the angular module using the filter function. The filter function accepts two arguments:

  • Name: The first argument of the filter function is a name.
  • Options Array: the second argument of the filter function is an options array. It is part of Angular's dependency injection and is used to pass services into the filter. The last element of the options array should be a function which contains the filter code.

The filter function returns a function that will process the data and return the results. In this case, we have a single argument passed into the filter, and that is the service which contains Angular filters. The function to perform the filtering accepts a single argument, named input. When the filter is triggered, the $filter service will format the input and return the results.

You can invoke the filter function from the view, like this:


Date formatted with custom Filter: {{unformattedDate | formatDate}}<br/>

The app should now return something that looks like this:

See the code work or play with the Plunkr

Can I use an Angular Filter in a Controller?

Your custom filters can also be used inside of an Angular controller. You pass it in, just as if it were a service. Instead of accessing the name of the filter 'formatDate', add filter to the end, and access formatDateFilter. The value of the filter service is a function which you can call inside the controller code:


angular.module('FilterDemo').controller('FilterDemoController',['$scope','formatDateFilter',
function($scope,formatDateFilter){
$scope.unformattedDate = new Date();
$scope.formattedDate = formatDateFilter($scope.unformattedDate);
}
]
);

A new scope variable named formattedDate is referenced. The value of that variable uses the formatDateFilter and passes in the unformattedDate value. You can reference the formattedDate in the view code as if it were any other scope variable: Date formatted inside Controller: {{formattedDate}}

See the code work or play with the Plunkr

Final Thoughts

This is a pretty simple example of how to use a filter; but you can do much more complex things. The coolest thing I've seen done is a client app that uses filters for localization. They just need to change one config variable to switch the app to a different language.

Sign up for DotComIt's Monthly Technical Newsletter

How do you solve AngularJS $injector:unpr errors?

I was doing some experiments so that I could understand Filters and ran into this error in AngularJS recently:


Error: [$injector:unpr] http://errors.angularjs.org/1.5.0-beta.1/$injector/unpr?p0=formatDateFilterProvider%20%3C-%20formatDateFilter
at Error (native)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js:6:423
at http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js:40:451
at Object.d [as get] (http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js:38:432)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js:41:23
at Object.d [as get] (http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js:38:432)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js:149:441
at S (http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js:112:120)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js:110:212
at m (http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js:7:331)

The problem was that AngularJS was not able to find my filter. I've run into similar problems with controllers and services. Why would there be a problem? Here are a few reasons I've seen similar errors in the past:

  • There is a typo in the filter name when the filter is created
  • There is a typo in the filter name when you try to access the filter
  • The Filter is defined in a different module and you didn't pass that module in as an argument to the current module.
  • The Filter name got reused, overwriting the original filter.
  • The application name got reused after the filter was created, essentially replacing the module object that had your filter.

Although I talk about Filters, the above text could cause issues with Modules or Controllers or Services. My current problem was the last item.

When I used to create AngularJS applications, I would store the application in a global JavaScript variable which could be used elsewhere, like this:


var myModule = angular.module('FilterDemo', [])
myModule.filter('noFormat',function(){
return function(input) {
return input
}
});

However, global variables are universally considered bad, so I recently found a new way to create filters, controllers, and services on the same module:


angular.module('FilterDemo', [])
angular.module('FilterDemo').filter('formatSomething',function(){
return function(input) {
return $filter('date')(input, 'shortDate')
}
});

The code above, works great and I'm not creating any global variables to clutter up the application. However, in a recent app I was building I Was doing this:


angular.module('FilterDemo', [])
angular.module('FilterDemo', []).filter('formatSomething',function(){
return function(input) {
return $filter('date')(input, 'shortDate')
}
});
angular.module('FilterDemo', []).controller('someController',['$scope',function($scope){
// controller code here
}]);

When trying to access the filter in the view, I Was getting errors similar to the one above. I was scratching my head against this one for a while until I figured it out. Can you see the differences between the two code snippets.

In the first--working--snippet I did not specify the option array when accessing the module. My interpertation is that, this:


angular.module('FilterDemo', [])

Creates a new module, while this:


angular.module('FilterDemo')

returns an existing module. Creating a new module, with the same name as a previous created module, you will lose all existing filters and controllers and services. That is why I was getting an injector error.

This is what happens when I try to write code from memory without looking at "how I did it last time".

Hopefully this helps someone.

Sign up for DotComIt's Monthly Technical Newsletter

How do I display hidden text in my table on rollover using CSS?

I was building out an app for a client and they had some wireframes that showed a list of users. The wireframes had a bunch of user data; but the client wanted some of the data hidden until the user rolled over the table row. How do I do that? CSS is the answer.

First, create a CSS class:


#tableWithHiddenData{

}

Now, create a style for hidden data:


#tableWithHiddenData .rollOverText{
display:none;
}

The display CSS element is used to control layout. By giving it the value of none; the information will, essentially, be hidden.

Next, we'll need some CSS to display the hidden text on hover:


#tableWithHiddenData tr:hover .rollOverText{
display:block;
}

These are the three CSS elements that are needed, now lets create the table. Since, for my use case, I was displaying user data, our table will contain two columns. One for a user's name and one for the username. The a will always be displayed and a username that is only displayed on rollover:


<table id="tableWithHiddenData">
<tr>
<th>Name</th>
<th>UserName</th>
</tr>
<tr>
<td>Jeffry Houser</td>
<td><div class="rollOverText">jhouser</div></td>
</tr>
<tr>
<td>Someone Else</td>
<td><div class="rollOverText">someUser41</div></td>
</tr>
<tr>
<td>A Third User</td>
<td><div class="rollOverText">LuckyThird</div></td>
</tr>
</table>

Try this out on Plunkr.

Sign up for DotComIt's Monthly Technical Newsletter

Happy Anniversary

A few milestones happened to me this year. This blog turned 10, so my Internet writings have been floating around for a decade. DotComIt started its 17th year in business. Personally, I entered another decade. This is intended to be a retrospective mushy posts about how awesome I am. :-)

The Blog

Social media wasn't a thing when I started blogging. I didn't have a Facebook account, and Twitter didn't exist. All my friends were on MySpace and mp3.com was the place to go to discover new music. When stupid Internet quizzes came up, I would discover them on someone else's blog and would post results here. People used RSS readers to keep up on their friend's blogs, and aggregators could bring you lots of traffic.

Today, most interaction has moved to social media. I think the blog form is relevant for dispensing information, such as tutorials or screencasts, but they do not work as a place for discussion. The end result is that I blog less than I used to. Most of my recent blog posts are curated from the DotComIt technical newsletter, which focuses on longer in-depth articles. I've been writing the newsletter almost monthly since 2008, and that is a lot of content.

On a personal note; I think the design of this blog is in dire need of an update. I uses the default BlogCFC theme, and I haven't updated it in years. It doesn't even feature a rich text editor for writing blog posts, so all the HTML markup is stuff I write manually. I think my blog content could use a high level scrubbing as some of the posts are not relevant. I sometimes think that I should use this domain for something other than a Blog; with some sections dedicated to music and the sort. Such changes will have to wait for another day.

By the Numbers

I've written 686 posts on this blog; which averages to 5.7 posts per month. But, averages don't tell the real story. This graph shows the number of posts I made per year:

The first drop you see is in 2007; the same year I started The Flex Show. It continues to drop in 2008 as I prepared to launch Flextras. The Flextras blog was launched in the beginning of 2009. There is a bump in posts in 2012; the Year I shut down The Flex Show. In 2013 I shut down Flextras, open sourced the components, and started work on the Life After Flex series. Even though the stats of this blog don't show it; I was creating lots of content, just much of it was for other places.

When Life After Flex launched in 2014 and after writing that I took some time off. I'm only now getting back into the swing of things. If I follow my standard, next year will see a lot of blogging. Unless I update my Life After Flex course for AngularJS 2.0 [which is a possibility, but not guaranteed].

Categories Per Year

In my early days, my posts were a lot more varied; with everything from movie reviews to game reviews to whatever I tickled my fancy. Over time this blog became a lot more focused on technical content. Here are some of the top topics per year

Year Top Topics
2005 ColdFusion took the lead for my most blogged about topic this year.
2006 ColdFusion once again was the top of my blogging list in 2006.
2007 ColdFusion and Flex are head to head this year, with 34 posts on each one.
2008 Flex overtook CF as my top topic.
2009 Flex once retains the top spot.
2010 Flex is top again
2011 Flex is the top
2012 Writing and Presenting has the same amount of posts as Flex this year. I think this is the year when I published all the archives from my ColdFusion Developer's Journal column.
2013 AngularJS ties the top spot with ColdFusion and writing and presenting.
2014 AngularJS and Writing and Presenting take the top spot again.
2015 AngularJS and JavaScript hold the top position [so far] for 2015.

My top posts follow, relatively, the technologies I have worked with in my career. Starting with a lot of ColdFusion stuff, moving onto Flex, and most recently AngularJS and JavaScript.

In terms of specific content, I finally wrote a technical blog post that gets a lot of traction. It is a blog post on the solution to a problem I had with AngularJS and refreshing views.

I think the blog post is relatively well written, and was accidentally optimized for search engines. It has a question in the subject line and provides a few different solutions. I bet a lot of people having the same problem typed the exact question into Google. I think it is the rare case where I tackled a problem a lot of people have and wrote a detailed solution to the problem. I also provided plunkers with samples; which I don't often do.

My second most famous blog post is one on customer service issues I had with tracfone, a pay as you go service provider. I wrote it as a on-off post, and it is a bit embarrassing how popular it became.

Personal vs Professional Posts

When I launched this blog, aggregators and RSS feeds were all the rage. I decided to categorize every blog post as either a personal blog post or a professional blog post. That way folks could easily follow my technical content without the unrelated content; or vice versa. This worked out well, a friend even syndicated my personal feed to LiveJournal at one point.

My number of personal and professional posts, are roughly equal, with there being slightly more Professional Posts in most years.

I find the numbers interesting. ;)

ColdFusion vs Flex Vs AngularJS

The three main technical topics I write about are ColdFusion, AngularJS, and Flex mirroring the three main technologies I have used in my career. How do these stack up:

No surprise, here; there is a big jump in ColdFusion posts in the beginning, and that declines as Flex rises to the top. AngularJS is almost non-existent, but you see a slight rise in recent years. If all goes well, you'll see more AngularJS oriented posts next year.

The Business

Enough about the Blog; DotComIt has been going for 16 years. Sometimes I feel lucky I'm still around. I have seen a lot of businesses come and go; and many colleagues have started businesses only to grab a full time job shortly thereafter. I've used my consulting success to dabble in multiple different ventures, from Creating Flex Components to self publishing a training course on AngularJS. None of those ventures turned out to be profitable enough to shutter the consulting side of the business, and I'm fine with that. I'm lucky to have a solid base of clients that provide me with flexibility to be me. There is always room for more if you're interested.

Half way through the Flex craze, I noticed that I got a lot of respect for being a business owner. Most of my friends consider me a success and I love talking about business, sometimes even more than coding.

Right now; I'm in a rare spot where I don't have a second venture ongoing; but I can't wait to see what I jump into next.

Thank you to all the clients who have hired me; continue to keep my plate full, and those who will hire me in the future.

What about Me?

For most of my professional career, I have striven to become a leading expert in what I do. I speak at user groups and conferences. I write books, produce podcasts, and participate in user forums. With the decline of Flash, and Flex, the community I attached myself too has scattered and I've lost some focus as a result. I have not decided what I want to conquer next; and do not have a community at the moment.

Looking back, I think I've reinvented myself three major times during my professional career.

The Programmer

The first iteration was Jeffry the programmer. At the start of my career I was employed by a business to business consulting firm. I did a lot of Lotus Notes development, but also touched on other technologies such as iCat and ColdFusion. The work was fast paced, and I learned more than I could ever imagine. We pushed the boundaries of technology at the time. But, the pace burnt me out. I only realize this in retrospect. I left there quite hastily to do something different.

The Business Owner

The second iteration is Jeffry the Business Owner. I left my former employer with no plan. Thankfully the dot com boom was crazy and I was able to get some consulting work via word of mouth. I feel into running a business like no one else should. At this time I also had the opportunity to write a book for Osborne McGrawhill; which I took. I still don't know why the acquisitions editor reached out to me. He actually told me that if he were the Emperor I'd be the one he would clone. I had a knack for meeting deadlines that is unusual in the publishing industry.

The first book lead to more writing and presenting opportunities, and that worked as my businesses promotional arm. It didn't bring me clients directly, but it did help me land projects. When you teach others, people who have no ability to evaluate your skill are willing to assume you know what you're doing. It makes you an easy sell to the business bean counters because it gives confidence you can do what you claim.

The Product Creator

My desire was always to build and support a product instead of getting into the consulting grind. When Flex came along, I decided to go all in. I started work on Flextras immediately. I redirected my writing skills to podcasting in an attempt to build an audience of Flex developers. I started spending a lot of time on StackOverflow to answer Flex based questions.

I think I did a lot right (and a lot wrong); but in the end Flash lost relevance and the product business failed. I fell back to the consulting grind and have been juggling multiple clients ever since.

What Next?

I have no idea what is next for me. I'm focusing on servicing existing clients; biding my time and vetting different ideas. I haven't had an idea worth chasing after yet. What would you like to see me do?

Why Won't ColdFusion 10 show my cfgraph on IIS 7.5?

I just spent half a day trying to figure out why ColdFusion 10 would not show my cfgraphs. I solved it, but not by the 'usual' means.

I have a production server locked down via the CF10 lockdown guide. It has been chugging along for a few years without any issues.

I was working on some code to generate some reports on some database data. Everything was working fine on my local install of the code; but when I pushed to production my graphs were blank.

The graph image was generated using something similar to this:


/CFIDE/GraphData.cfm?graphCache=wc50&graphID=Images/2834639300100060.PNG

Because the server is locked down; the CFIDE directory is not located in the root directory of the server. Even if it were, GraphData.cfm does not refer to an actual file, but rather a server mapping.

The first thing I verified was that the graph data was actually being created. I thought that perhaps CF did not have write access to the directory it used to generate the chart files. Look here:


{cfinstallDirectory}\cfusion\charting\cache

If you see files being generated in that directory, then access it not the problem. It was not for me.

Why was I getting broken image links when trying to load a page with dead graphs?

There are a people with this problem on the web, but most of the fixes did not work for me. Manually created a CFIDE folder and a GraphData.cfm folder did not work for me.

Manually creating an ide.cfm file in the CFIDE/main directory did not work for me.

So, what did work?

It turns out at the IIS level I had blocked a lot of URLs related to CFIDE directory. So, to fix my solution I had to remove these blocks.

Follow these steps:

  1. Open up your IIS Control Panel
  2. Click on Request Filtering
  3. Click on URL. If you have setup IIS to block the CFIDE folders, you'll probably see something like this:

  4. Right click on CFIDE/GraphData and click remove

My graphs immediately started showing up. Like magic!

Sign up for DotComIt's Monthly Technical Newsletter

Why use a self executing function with AngularJS?

I was recently reviewing some code for a client, and I noticed that a lot of JavaScript code was wrapped in a self executing function. Why would you do that? This is my take.

What is a Javascript self executing function?

A self executing function is a function that is immediately invoked when the application launches. Formally, it should be called an Immediately-Invoked Function Expression (IIFE). The function doesn't execute itself; but rather the browser does during page rendering.

This is a generic self executing function:


(function () {
console.log('function executed');
})();

An anonymous function is wrapped in parenthesis, and then '()' is put at the end. When the page initializes, the browser will execute this function once.

Why use an IIFE?

The main purpose of a IIFE is for code encapsulation. Variables you create inside the IIFE are not exposed as global JavaScript variables, and therefore cannot be affected inadvertently by other code that runs in your page. Primarily, I consider the approach scope control.

When dealing with large applications, or multiple developers, using an IIFE helps prevent namespace conflicts. Two people using the same variable name for different things will cause odd results for your application.

Using a self executing function with AngularJS

This is how you might use an IIFE with AngularJS:


(function (angular) {
angular.module('testApp', []);
})(angular);

You'll notice that the angular framework is passed into the function as an argument. Inside the function, an Angular module is created. You could also create controllers, services, filters, or other Angular elements inside this function, something like this:


(function (angular) {
angular.module('testApp', []);
angular.module('testApp')controller('testController', ['$scope',function ($scope) {);
})(angular);

Or you could split them up into multiple, independent IIFE:


(function (angular) {
angular.module('testApp', []);
})(angular);
(function (angular) {
angular.module('testApp')controller('testController', ['$scope',function ($scope) {);
})(angular);

Anything JavaScript related can be put inside these self executing functions, so these would work for other frameworks, or any code.

Why use an IIFE with AngularJS?

Now that I showed you how to use an IIFE with AngularJS, the question is why? It is, primarily, a matter of personal preference. I see no direct benefit to using these with AngularJS. Your angular code is already going to be encapsulated in functions including controllers, services, directives, and the sort. So, the bulk of your JavaScript is already encapsulated, and protected from mistaken naming conflicts or unprotected change.

As best I Can see; it comes down to a matter of personal preference.

Here are some good reading on the topic

Sign up for DotComIt's Monthly Technical Newsletter

Creating a Popup with AngularJS and Bootstrap

I wrote up this tutorial for one of DotComIt's monthly newsletters and decided to share it here.

I was recently working on a client app and had to display a form in a popup. Popups were dead simple in the Flex world, because of components such as the TitleWindow and the PopUpManager. In the HTML(5) world they are not as straight forward. This article explains how to do that with AngularJS and Bootstrap.

Import the Libraries

The first step is to import the libraries needed into an HTML page. We'll be using AngularJS, Bootstrap, and UI Bootstrap:


<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.4.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">

The first script tag loads the AngularJS library from the Google content delivery network (CDN). The second loads the UI Bootstrap library directly from Github. This is an Angular implementation of the Twitter's Bootstrap. The final statement is a link tag which is used to load the Bootstrap CSS. The Bootstrap CSS is loaded from another CDN. With these three libraries in place, we are ready to create our first popup.

Create a Simple Popup

The first step in creating an Angular application is to define the Angular module:


angular.module('PopupDemo', ['ui.bootstrap']);

This creates an Angular module named PopupDemo. A single argument is passed into the module, the ui.bootstrap. This allows the ui.bootstrap components to be usable from within this Angular module.

Next, create a controller:


angular.module('PopupDemo')
.controller('PopupDemoController',
['$scope','$modal',
function ($scope, $modal) {
}
]
);

This creates a controller, named PopupDemoController on the PopupDemo module. A controller is just a function in AngularJS. There are two arguments are passed into the controller function. The first is the $scope service which is used to share information between the controller and the view. The second is a $modal service, which comes from the UI Bootstrap library. It allows us to create, and control, the popup.

Inside the PopupDemoController, create this function to open the popup:


$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'Popup.html',
});
}

The open function is put in the scope, so that it can be triggered from the controller's view. An open() function is called on the $modal service. The argument into the open() function is an object representing parameters used to create the modal. For now we just specify a single argument, the templateUrl. The templateUrl is the URL location of a view template contains the popup's contents. The results of the $modal.open() function are saved in a local variable, modalInstance.

This is the view template:


Some Popup Here

The template is simple for the purposes of this sample, but we'll make it more complex later in this article.

The view template is kept simple for this first sample, It includes no HTML or references to Angular scope variables. We'll expand on that later in this article. Now let's fill in the rest of our main application:


<body ng-app="PopupDemo">
<div ng-controller="PopupDemoController">
<a ng-click="open()" >Open Popup</a>
</div>
</body>

The PopupDemo module is put on the body tag with the ngApp attribute. The PopupDemoController is put on a div inside it. The div contents contains a single anchor, which will call the open() method in the controller.

The page should look like this:

Click the open popup link to see the popup:

This simple example shows the basics of creating a popup. Test out this app here.

Expand the Popup Template

Let's take a look at the popup template file. As part of Bootstrap there are some special CSS classes to allow us to add formatting to the popup:


<div class="modal-header">
<h3 class="modal-title">Header</h3>
</div>
<div class="modal-body">
Main Content
</div>
<div class="modal-footer">
<button class="btn btn-warning" type="button"
ng-click="close()">
Cancel</button>
</div>

The template is now split up into three sections: a header, a body, and a footer. Each one is distinguished by a div with a special CSS style. The header contains a header tag with the modal-title class. The body should contain the main content of your popup. The footer contains a close button. The close button calls a close() method. Where does the close() method exist? We'll need to give the popup its own controller.

The controller for the popup can be put in the main index file for the purposes of this sample:


angular.module('PopupDemo').controller('PopupInstanceController',
['$scope','$modalInstance',
function ($scope, $modalInstance) {
$scope.close = function () {
$modalInstance.dismiss('cancel');
};
}
]
);

There are two services passed into the controller function; the $scope and the $modalInstance. The $scope is used to share information between the view and the controller. $modalInstance is a reference to the current popup. The close function is created in the $scope so that it can be triggered by the button in the template. It calls the dismiss function on the $modalInstance service, effectively closing the popup. When the popup is opened, we need to tell Angular to associate the new controller with the popup. This is done with the controller argument into the $modal.open() function:


$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'Popup.html',
controller: 'PopupInstanceController',
});
}

The value of the controller property is a string which refers to the name of the controller.

Reload the app:

The initial app doesn't look much different than sample 1. Now click the open link:

The popup looks much nicer. Click the close button to close the popup. Play with this sample here.

Pass Items into the Popup

What if you are using the popup to edit something? The popup will need access to the object you want to edit. You can pass data to the popup using the resolve property when opening the modal. This next sample will demonstrates how to send a value to the popup. IT uses the resolve parameter of the $modal service:


$scope.open = function (title) {
var modalInstance = $modal.open({
templateUrl: 'Popup.html',
controller: 'PopupInstanceController',
resolve: {
title: function () {
return title;
}
}
});
}

The open() function now accepts an argument, a title. The configuration object of the $modal.open() function as a new property: resolve. The resolve option is an object and each property of the object will be passed into the popup's controller. In this case, the title contains a function which returns the title argument. This could also be used to pass values from the $scope or other services to the pop up controller.

Next, look at the controller changes:


angular.module('PopupDemo').controller('PopupInstanceController',
['$scope','$modalInstance','title',
function ($scope, $modalInstance, title) {
$scope.title = title
$scope.close = function () {
$modalInstance.dismiss('cancel');
};
}
]
);

A new argument is added to the controller, named title. This is treated as if it were any other Angular service. Except in this case it comes from the resolve property of the $modal.open() command instead of a service we created on the angular module. The title is saved into the scope so it can be accessed within the popup template:


<div class="modal-header">
<h3 class="modal-title">{{title}}</h3>
</div>

Now go back to the main page, and let's add a few links that change the title of the popup:


<body ng-app="PopupDemo">
<div ng-controller="PopupDemoController">
<a ng-click="open('Edit Item')" >Open Edit Item Popup</a><Br/>
<a ng-click="open('New Item')" >Open New Item Popup</a>
</div>
</body>

The edit item link passes the value of 'Edit Item' to the open() method. The add item link passes the value of 'New Item' to the open() method.

Launch the app and you'll see something like this:

Click the "Open Edit Item Popup" link to see this popup:

Click the "Open New Item Popup" link to see this:

Play with this Sample. Things can get much more complex in real world apps, but this demonstrates how you might pass data to the popup.

Final Thoughts

When I write these articles I'm never sure when to stop writing. I could easily double the size of this article with additional info or samples of using Bootstrap popups in AngularJS. But, this feels like a natural place to stop.

How can I help you this week?

Sign up for DotComIt's Monthly Technical Newsletter

More Entries

All Content Copyright 2005, 2006, 2007, 2008, 2009 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002.