Thursday, December 31, 2015

2015 in Review

Last year was an exciting year on multiple levels. It was my first year directing the application development practice at iVision. It was exciting to grow the team, reach new customers, and engage in new projects ranging from complete rewrites (link to case study PDF) to Silverlight migrations and Internet of Things (IoT) platforms featuring real-time monitoring and analytics. The bulk of those projects involved creating responsive web apps leveraging the Angular AWESM stack.

The industry experienced exciting changes as well. Single page apps are now readily accepted by the enterprise and JavaScript development on platforms like Node.js is now considered mainstream.

Agile adoption is increasing and we engaged in multiple projects (link to case study PDF) last year to train companies on how to adopt Agile and implement it leveraging tools like Visual Studio Team Services. More importantly, DevOps is not just a catch phrase but a real process being leveraged in production to enable continual delivery so that companies can release products weekly or even daily to meet the fast-paced demands of business and technology.

Cross-platform solutions like Apache Cordova and Electron continue to gain momentum while JavaScript itself is rapidly evolving through new specifications that are being adopted at an accelerated rate.

I try to stay on top of trends and provide links to exciting posts and articles through my Twitter feed.

jeremytwitter

According to Twitter, the majority of you who follow me enjoy technology and tech news (surprise!), are technical professionals (almost half) and/or self-employed (one in five). Just over half of you are married, and nine out of ten are male.

On average I gain three new followers a day. I don’t track people who stop following but given any single day I’d say it’s probably six steps forward, three steps back. Some people follow only for a follow back, some prune their lists and others either aren’t interested in the content or come across a tweet they don’t like and jump ship.

What’s more interesting to me is out of the thousands of tweets I post, only a few stand out as interesting based on impressions, engagement, and clicks. Not surprisingly, the highest percentage of engagement is not from news tweets, but conversations (for example, when I ask a question or respond to someone who mentioned me).

Here are my top three tweets in various categories from the previous quarter:

Most Viewed

1. Overriding services (both core and custom) in #AngularJS http://t.co/dAt9OFv6oC #JavaScript

2. Surprise! Microsoft $MSFT is #Agile. https://t.co/rqfKR9Dxiw Case study of agile transformation at a billion dollar corporation

3. The #React Native extension for #VisualStudio @Code https://t.co/DbP0XGesil #TACO (Tools for #Apache #Cordova)

Most Liked

1. Overriding services (both core and custom) in #AngularJS http://t.co/dAt9OFv6oC #JavaScript

2. Back to basics: #AngularJS 2 with plain #JavaScript: no #TypeScript, no #ECMAScript6 #ES6 https://t.co/Y3bJN9RL4n

3. #WPF not only lives, it now has a new home with #JavaScript https://t.co/EIrFkoJiBb Check out "Granular" and run WPF in the browser

Most Clicked

1. Overriding services (both core and custom) in #AngularJS http://t.co/dAt9OFv6oC #JavaScript

2. Back to basics: #AngularJS 2 with plain #JavaScript: no #TypeScript, no #ECMAScript6 #ES6 https://t.co/Y3bJN9RL4n

3. Object.observe: fun while it lasted, now #AngularJS and #ReactJS cited as reasons it will be withdrawn from spec https://t.co/oFYL6uQjkU

I’m going to guess the majority of my followers have a bit of interest in Angular. What do you think?

C#:er IMage

When I created my blog in March of 2009, I did not imagine it would last this long. Of course, the topic is more JavaScript than C# so the title has grown stale, but readership is still steady.

blog2015

Most visitors stay at least a little while and one in five move on to other pages (that’s the “bounce rate.”) The gender gap persists on my blog (nine of out ten are male), and according to google almost half of the visitors are between the ages of 25 and 34 (glad this programmer with 41 years can still appeal to the younger crowd!)

I’ve had a fairly consistent international audience over the years. This is the breakdown from 2015:

countryblog2015

In previous years the Netherlands ranked higher. I can’t prove it definitively but I strongly suspect the drop of visitors from that region coincided with my shift from Silverlight to other technologies.

When I started my blog, Internet Explorer was king. Now it runs a distant third, with Chrome representing 67% of my audience, Firefox 13%, just 9% from Internet Explorer and the rest from Safari, Edge, Opera, and various other browsers.

One in ten visitors accessed the blog from their mobile phone and 3% from their tablet.

A large amount of referral traffic was attributed to my partnership with WebCodeGeeks.com. The second largest source was Twitter, followed by the Code Project and Stack Overflow.

Ironically, the top search terms that brought people to my site are all Angular-related with the exception of one. Apparently my Windows 8 article about using symbols from the Segoe UI font is very popular. Here are the top five searches that landed people on my blog this year:

1. angular broadcast
2. segoe ui symbol
3. angular emit
4. angularjs broadcast
5. angular events

Apparently, people are very interested in Angular events!

Finally, it’s always interesting to see what blog posts are read the most. Last year my post on the Top 5 Mistakes Angular Developers Make dominated, followed by my 5-year old but most popular blog post of all time (Model-View-View Model Explained), then the Segoe UI Symbol post, Ten Reasons Web Developers should learn Angular at number four, and Angular Project Essentials in the number five spot.

I asked the audience at a conference recently why so many attended a talk I gave on Enterprise JavaScript, and the unaminous reply was that I promised to share case studies “from the real world” and how this works in actual projects.

I look forward to doing more of the same in 2016. My team at iVision is growing and our goal is to work on more cutting edge enterprise projects that will continue to give us insights across verticals and projects and empower us to establish and follow best practices based on our experience as we move into cross-platform apps and adopt new frameworks like Angular 2.0 and Aurelia.

I will continue to blog, author articles, publish videos, and speak at user groups and conferences about those experiences because my personal mission is to empower developers to achieve their dreams. It is my sincere wish for you to achieve or move closer to yours in 2016.

Thank you all for helping make 2015 an abundant year. I wish you all a blessed and fulfilling 2016.

If you have time, why not share some of your own highlights from 2015 and goals for 2016 in the comments section below? We are all part of a global community and grow stronger when we share and collaborate.

Happy New Year!

Wednesday, December 23, 2015

Three Shades of Angular

In 2014 I presented at the Atlanta Code Camp and walked through building an AngularJS app starting from file … new. I used test-driven development to demonstrate how to create a functional application. I also wanted to demonstrate an app with multiple controllers that communicate with each other yet don’t rely on $scope, $watch, or even event broadcasting.

You can view the source for the Angular health app, along with instructions to step through the build iterations, in this GitHub repository.

After years of building business apps with Angular I find it helps facilitate some incredible scenarios, like this total rewrite of a Silverlight audit tool I did for a local physicians’ group:
angularcasestudy
Both Angular and JavaScript have been moving at a fast pace and to keep up with the changes I created two new projects based on the original example app.

ECMAScript2015 (also known as ECMAScript 6 and ES 6) is right around the corner. This is a new version of the standardized JavaScript specification that introduces concepts like classes and built-in support for Asynchronous Module Definitions (AMD). Fortunately, you don’t have to wait for browsers to support ES6 because there are tools available now that allow you to write code in ES6 and “transpile” it to the current version, ECMAScript 5.

To see an example of that in action, check out the Angular ES6 Health App. This is the same application, rewritten using the new features built into ES6. It is compiled to ES5 using Babel. I also used the combination of browserify and babelify to transpile the project into a single file for performance (as opposed to dynamically loading the modules). Don’t worry, I have an example of dynamic loading in the third Angular example.

Being able to work on tomorrow’s technology today is fairly exciting. Another way to tackle ECMAScript 6 is to leverage TypeScript. This is a superset of JavaScript that closely follows future specifications and compiles to a target version of your choice. It is the language being used by the Angular team to build Angular 2.0.

If you want to see what the same app looks like using TypeScript and the next version of Angular (that as of this blog post is in beta), take a look at the Angular 2.0 Health App. This is the same app migrated to use Angular 2.0 beta, TypeScript, and AMD for dynamic module loading.

The migration wasn’t straightforward so I wrote about it along with my thoughts on Angular 2.0 in the post Angular 2.0: Opinions, Commentary, and a Migration Case Study.

I hope these different shades of Angular give you a good idea of what to expect and how to prepare today for tomorrow’s technology. I expect adoption of both ES6 and Angular 2.0 to be rapid in 2016. It was a great learning experience for me and I look forward to building more modern web apps with a newer JavaScript that has grown up to embrace the enterprise.

Tuesday, December 22, 2015

Case Study: Migrating Angular 1.x to 2.0 and Observations about Angular 2

Angular is a framework designed to make it easier to build client applications (that is, apps written with JavaScript and HTML that run on various devices, including mobile devices and browsers). Business users often expect a rich user experience and don’t like to compromise on features just because the app is delivered over the web or via a mobile device instead of installed on a desktop. For this reason, an approach to building apps called Single Page Applications (SPA) has evolved. Angular provides built-in support for SPA via templates, components, services, and tools that help developers call web services and manipulate the data that is returned.

To answer that question, I migrated my existing Angular Health App to 2.0, then wrote a blog post with the details of the Angular migration as well as my overall observations about Angular 2. Read it here.



I hope you enjoy!

Jeremy Likness

Front-End Dev Back-End Nostalgia Tue Dec 22 2015

Friday, December 18, 2015

WordPress goes to NodeJs, Get to Know Visual Studio Code, Angular 2 Components Fri Dec 18 2015

Huge news today as WordPress announces dropping PHP and moving to NodeJS. Coverage of Visual Studio Code extensions and more framework fun covering ReactJs, Angular 2, and more.

Enjoy!

Thursday, December 17, 2015

AngularJS 2 in Beta, Cross-Platform .NET Framework, Visual Studio Code on Thu Dec 17 2015

In this series of links, AngularJS grows up to beta status and gets compared to other frameworks; the .NET Framework goes cross-platform and gets some SOAP, and Visual Studio Code goes native!

Tuesday, December 15, 2015

Progressive Web Apps, Docker, ReactJS and More Tue Dec 15 2015

Posts covering progressive web apps, predictions for OpenStack and Docker, business decisions that drive ReactJS and understanding promises.

Jeremy Likness

Saturday, December 12, 2015

AngularJS Performance, Visual Studio Team Services Customization, Continuum and More Sat Dec 12 2015

Yesterday featured posts that addressed AngularJS performance, unit testing JavaScript, some exciting updates to Visual Studio Team Services and 2015, and my initial experiences with the Lumia 950 and Continuum.

Jeremy Likness

Friday, December 11, 2015

DevOps, Cross-Platform Apps, Docker and IoT on Dec 11 2015

Here’s my round-up of interesting news and blog posts from the past day!

Jeremy Likness

Thursday, December 10, 2015

Day in Development Recap Thu Dec 10 2015

Tuesday, November 24, 2015

Continual Delivery of an AngularJS ASP.NET MVC Web API Entity Framework SQL App to Amazon AWS using Visual Studio Team Services

I know, that title is a mouthful. But that’s exactly what it is! A team at my company, iVision, has been working on an app using the AWESM stack for almost a year now. The app is structured like this:

  • A SQL Database, tracked in source control as a database project
  • A repository layer based on Entity Framework
  • A REST-based web services layer built as an ASP.NET Web API project
  • A shared security library that allows sign-on from various sources and uses JWT to transport authentication and authorization information then rebuild the custom IPrincipal and IIdentity using a DelegatingHandler
  • An ASP.NET MVC application to host templates (we used this so we can restrict access to templates based on security using the built-in Authorize attribute functionality)
  • A single page Angular app built with TypeScript that is now hundreds of components and pages
  • NUnit unit and integration tests, with Jasmine tests for the client

The app is a total rewrite of an existing system that uses an object-oriented database. The environment is designed to continually synchronize data from the object-oriented database to the SQL database for testing and validation purposes. This gives us “continuous migration” so there are no surprises at go-live – all operations can be verified real-time against the legacy system.

The backlog contains hundreds of items for us to migrate over. Fortunately, the free software we use to manage it gives us “at a glance” visibility into where we are at. For example, this chart of story points by state makes it immediately clear we’re just under halfway through the backlog:

image

You may or may not know that Visual Studio Team Services (VSTS) features a full cross-platform web-based build system that supports DevOps start to finish. We’ve been using this system to track requirements (backlog), plan sprint iterations, map team capacity, conduct daily scrums, track burn down and provide real-time transparency to the customer of our projected release date based on average velocity over time. It also serves as our source code repository, continuous integration server, and finally continual delivery.

It’s always exciting to see a good plan come together when the sprint burndown looks like this:

image

The customer already had an existing setup with Amazon AWS, so we are not delivering to Azure. Not a problem! The VSTS system made perfect sense given the team size is four developers and it comes with five free licenses. The new build system provides a simple link to download and install an agent on the target machine. The agent enables me to authenticate with VSTS and configure attributes about the environment to enable automated builds right from the AWS environment. As long as the machine has a path to the Internet, there are no crazy firewall rules to tweak.

Once the agent is installed (in this case as a windows service) I never have to log onto the box again – everything is managed through the web-based build interface.

At a 5,000’ level the build steps I chose are captured here:

image

By default the build process will synchronize the source code on the build machine with the main repository. I chose not to clean it each time which avoids pulling down the full source tree. Despite the fact the app represents hundreds of thousands of lines of SQL, TypeScript, and C# code, the entire build process takes only a few minutes.

The first step is to build the solution. This will catch any errors early on and set up the environment to make the subsequent steps run more easily. At this stage the app is built but nothing has been deployed.

The next step is a PowerShell script I wrote to backup the existing database. The configuration in VSTS is simple: I just enter the path to the script. The script itself loads some dependencies, checks to see if an existing backup exists and deletes it, then performs the backup itself.

image

The next step is a Visual Studio build step, but instead of pointing to the solution, it points to the SQL project. The Publish target followed by a path to a publish file triggers the database upgrade. It uses the publish profile to connect to the local database, compare against the source version, then update any changes. If there are any issues the database was just backed up so we can easily restore after testing the upgrade.

image

The next step is to backup the internal website in case the deployment has an issue (so it is easy and fast to rollback). For this I use the “Copy and Publish Build Artifacts” block.

image

Finally, I can deploy the ASP.NET MVC Angular application. Because there are multiple web applications in the solution, I deploy at the project level using the “msbuild” block. The deployment will automatically apply my web.config transforms so that the correct database, services URL, etc. are configured. Notice that I pass the property to deploy on build and give it a publishing profile that I previously set up and checked into source control. I don’t need to restore NuGet packages because that was taken care of with the initial solution-wide build.

image

The same steps (backup, build) are repeated for the Web API project. That’s it! After the last step, the database has been upgraded, the web and service sites updated with proper configurations, and the site is ready to access. All of this can be done with the push of a single button (or run on a regular schedule) and if any issues are encountered, the backup images can be used to restore to a previously known state.

It’s so easy, I had to double-check the deployed apps the first time I did it because it built so fast and ran successfully. This is just sharing some of the process; the full cycle will include unit and integration tests as well as a “smoke screen” that can be run at the end to verify the build succeeded by accessing the running application.

Because the entire process is managed by VSTS, we have full clarity of the process from the product backlog item to the build itself, with changesets automatically linking requirements to code changes and the builds they were deployed in. If the build fails, it automatically generates a defect so the team can look into the issue and resolve it immediately. Overall this streamlines the development lifecycle and puts high quality software into the hands of our customer more frequently.

Happy DevOps!

Tuesday, October 27, 2015

Introducing the AngularJS AWESM Stack

I recently presented the AngularJS AWESM stack at the Atlanta Code Camp. This is a stack I’ve been using successfully for nearly four years now. It includes the following components:

  • A is for AngularJS
  • W is for ASP.NET Web API
  • E is for Entity Framework
  • S is for SQL Server
  • M is for ASP.NET MVC

Each component of the stack is a piece of a larger puzzle that makes it easier to develop quality code faster for single page applications and line of business websites.

awesmstack

The abstract for this talk: “Single Page applications have taken the business world by storm and drive many responsive line of business web experiences. Fortunately Microsoft has done a great job of keeping pace and provides the backend elements needed to build a full stack solution for the enterprise. In this talk, Jeremy Likness demonstrates how AngularJS, Web API, Entity Framework, SQL Server and MVC (ASP.NET) work together to provide a comprehensive platform to build secure, scalable enterprise single page applications.”

To learn more about how I leverage the stack and why it is beneficial, take a look at the deck:

You can also access the sample code and PowerPoint presentation on GitHub: The AngularJS AWESM Stack.

Sunday, October 25, 2015

The Top 10 Lessons Learned from Enterprise JavaScript Development

A week ago I presented a talk at Atlanta’s ConnectJS conference. The title of the talk was “The Top 10 Lessons Learned in Enterprise JavaScript.” Because it was a JavaScript-focused talk I decided to author the presentation in JavaScript using one of Google’s Html5 projects.

top5lessons

You can view The Top 10 Lessons from Enterprise JavaScript Development and also browse the source. The deck features frames that load live content to make certain points, so it may take some time to initialize in your browser and may flash some warnings. I took snapshots of the slides with dependencies in case you have trouble loading it.

In the purest sense, Enterprise JavaScript is simply JavaScript used in applications that serve the enterprise, typically via line of business applications. It is typical for these projects to be larger than direct-to-consumer or “brochure site” code bases. Some projects span years and involve hundreds of thousands of lines of code. Another important aspect that differentiates this class of application is the size of the team. I’ve worked on teams with 25 developers simultaneously working in the same code base, and even larger teams exist.

To summarize the deck, after working with JavaScript in the enterprise for nearly two decades I’ve learned these lessons:

  1. Yes We Can! – although JavaScript began as a scripting language to glue Java applets to the DOM, we can absolutely build complex mission critical line of business apps now that the language and supporting frameworks have evolved.
  2. Dynamic Requires Strict Measures – when you are working with large teams the dynamic nature of the language can quickly turn the code into a nightmare. It makes a lot of sense to use languages like CoffeeScript or TypeScript to add form and structure when dealing with larger teams or code bases.
  3. Forget Java and C# – not really, they will still have a place, but with the advent of technologies like NodeJS you can truly write your full stack with one language.
  4. DOM stands for “Demonic Object Matrix” – I’ve found that a lot of the blame JavaScript receives isn’t because of the language itself, but the inconsistent implementation of the Document Object Model across browsers. That is why it is more important than ever to leverage libraries like jQuery and Bootstrap to “normalize” access to the DOM, styles, and behaviors.
  5. Live on the Edge – yes, there was a funeral for IE6. But then things got worse. In this day and age I fight as hard as I can to get out of the rut of writing backwards compatible software for older versioned browsers. Instead, I ask that companies live on the edge versions.
  6. TypeScript is like Coffee – no, not like CoffeeScript. I’ve witnessed the before and after or a team working in pure JavaScript and then migrating to TypeScript and it’s like hitting the nitro button in a race car. Even JavaScript purists on teams I’ve lead have told me after using it they really see the value and are glad we made the switch.
  7. Frameworks Save Lives – I’ve witnessed more than a few heated discussions in forums about sticking with pure JavaScript and avoiding frameworks like the plague. Typically it is the high and mighty architect pontificating about how they mastered the language and everyone should either become an expert or not write code. That’s great for forums and maybe to catch the eye of recruiters but in the real world time is money and frameworks help us scale and deliver applications more quickly. I can ramp an Angular developer onto an Angular project far more quickly than I could on a project that features “Jeremy’s super ultra perfect because he knows JavaScript proprietary framework.”
  8. Don’t Just Write It. Build It! – this simply means we no longer have to use NotePad to author JavaScript. It is integrated well into IDEs but more importantly we now have excellent frameworks like Gulp and Grunt to help build JavaScript and web-based applications. Use them! ASP.NET MVC 5 embraces this approach out of the box. Microsoft’s Visual Studio Online build process now features specific build steps for installing Node packages and using package manages like Bower to pull down dependencies, then build apps using Grunt or Gulp.
  9. Be Testy. Be Very Testy. – the day and age when JavaScript testing was difficult is long gone. There is no excuse not to test your JavaScript code and do it in an automated fashion that gates check-ins and runs in continuous integration and continual delivery processes. If you’re not testing, you’re not serious about your app.
  10. XML is Dead. Long live JSON! – do I really have to qualify this one? Let’s finally put to rest that chapter of SOAP and XSLT that we all participated in and were glad to move on from. JSON practically writes itself.

I’m done. There is a lot more detail in the deck so please view The Top 10 Lessons from Enterprise JavaScript Development and also browse the source.

Wednesday, August 26, 2015

Video: C.R.U.D. with ASP .NET MVC, Web API, Entity Framework and Kendo UI

Back in May I presented a session at TelerikNEXT that I designed for developers working on large-scale data-driven applications.

kendoui

In it, I demonstrated how the Telerik Kendo UI framework seamlessly integrates with the backend via ASP.NET MVC and Web API to build professional, robust line of business applications. I demonstrated how to create complex grids that support inline edits, complex templates and advanced filters, and sorts with only a few lines of JavaScript and C# code.

This session showed the power of Kendo UI framework’s MVVM data-binding to deliver forms that simplify validation and ensure the integrity of your data. It also covered how MVC seamlessly integrates with the client UI to power complex grids using the DataSourceRequest object that can literally filter, sort and page data with just a few lines of server side code (no custom stored procedures required!).

If you can’t access the video in this post, you can view it on YouTube by clicking this link. You can also access the deck:

… and the full source code.

Enjoy!

Sunday, June 14, 2015

Video: AngularJS and KendoUI

Although you may already know I’ve been working with AngularJS since it was in beta, you may not know I’ve had just as much experience with Telerik’s KendoUI control suite. For readers who aren’t familiar with KendoUI, it is a suite of jQuery-based UI widgets that also integrates directly with Angular. The core set of widgets is free and open source, and the more advanced widgets such as the grid are licensed.

kendouiangular

My team selected KendoUI for a Single Page Application we began writing several years ago that targeted HTML5. After reviewing several different vendors, we decided to go with KendoUI because the suite was built from the ground up with JavaScript, jQuery, and HTML5 in mind. Even before there was direct integration with Angular it served us well.

KendoUI_Badge_Horizontal_Certified_Big

As a result of my extensive experience working with the control suite I became one of the first certified KendoUI developers. I was also invited to speak at the TelerikNEXT conference about how AngularJS and KendoUI work together. You can view the presentation here:

The presentation is designed for developers with all levels of experience, from those who had never heard of Angular before to those who are advanced Angular developers and want to learn how to integrate KendoUI.

I also posted the full slide deck and source code that I used in the presentation to GitHub.

For easy navigation you can jump to the following sections of the video:

If you have some time I highly encourage you to watch the full video regardless of your experience. The examples range from a basic live demo demonstrating various Angular features to several miniature apps, including a rate grid and a health application that computes basal metabolic rate. I enjoyed giving the presentation and welcome all suggestions, comments, and feedback below.

Thank you,

signature[2]

Friday, June 5, 2015

An End-to-End AngularJS Guide

This isn’t a new eBook, a paperback or an online tutorial. I’ve been writing about Angular since it was in beta and have lots of material I believe is useful for developers with all levels of experience. Instead of forcing you to search haphazardly, this blog post organizes the content so you can jump directly to the post that you need.

The links have been organized into the following sections:

  • Background
  • Essentials
  • Advanced Topics
  • Testing
  • Examples
  • Best Practices
  • Modernizing Apps

I was very surprised when I started the task of organizing this content to see just how much there is. I hope you find this useful and welcome any and all comments and feedback.

Background (What and Why?)

A Different Angle: What is AngularJS?

10 Reasons Web Developers Should Learn AngularJS

Video: Angular and the .NET World

Single Page Applications (SPA): Your Browser is the OS

(Paid Video Curse): Fundamentals of AngularJS

Essentials

AngularJS Project Essentials

Understanding Providers, Factories, and Services in Angular

Understanding AngularJS Isolated Scope

Dependency Injection Explained via JavaScript

No Need to $watch AngularJS “Controller As”

Using AngularJS to angular.extend Your Code Quality

Quick Tip: Using a Filter with ngClass

Advanced Topics

AngularJS Lifetime Management, Lazy-Loading, and other Advanced Dependency Injection Techniques

AngularJS Debugging and Performance

Interception using Decorator and Lazy-Loading

Using Zone to Trigger Digest Loop for External Functions

Instrumenting Angular with ZoneJS

Testing

I’m not Mocking You, Just Your AngularJS Tests

AngularJS Integration Tests with Mocks and Magic

Examples

Let’s Build an AngularJS App!

Quick Tip: Counting Watches

Generate Mazes in AngularJS with 8-bit Algorithms

Real-time Communication in AngularJS with ($Q)orlate

Build a JavaScript Feed Reader in Under 10 Minutes with AngularJS

AngularJS Explained with Answers, Videos, and JsFiddles

Commodore 64 Meets AngularJS and TypeScript

Best Practices

The Top 5 Mistakes AngularJS Developers Make (5 Part Series)

Revisiting AngularJS with TypeScript

Modernizing Apps (Such as Silverlight)

AngularJS: The Modern HTML5 Answer to Silverlight’s MVVM

Feel free to comment with your favorite links on other sites and blogs as well.

signature[1]

Sunday, May 24, 2015

Understanding AngularJS Isolated Scope

In Angular, directives can have an isolate scope that creates an inner scope that is separated from the outer scope. There are a variety of options for mapping the outer scope to the inner scope, and this can often be a source of confusion. Recently, I’ve noticed a ton of up-votes for my answer to the Stackoverlow question: Differences among = & @ in Angular directive scope?

I created a simple jsFiddle to answer the question. The HTML markup looks like this:

<div ng-app="myApp" ng-controller="myController">
    <div>Outer bar: {{bar}}</div>
    <div>Status: {{status}}</div>
    <my-directive foo="bar"
                  literal="bar"
                  behavior="a+b"
                  call="update(1,val)" /> </div>

The code behind it:

var app = angular.module("myApp", []);
app.controller("myController", function ($scope) {
    $scope.status = 'Ready.';
    $scope.a = 1;
    $scope.b = 2;
    $scope.bar = 'This is bar.';
    $scope.update = function (parm1, parm2) {
        $scope.status = parm1 + ": " + parm2;
    }; }); app.directive("myDirective", function () {
    return {
        restrict: 'E',
        scope: {
            foo: '=',
            literal: '@',
            literalBehavior: '@behavior',
            behavior: '&',
            call: '&'
        },
        template: '<div>Inner bar: {{foo}}</div>' +
                  '<div>Inner literal: {{literal}}</div>' +
                  '<div>Literal Behavior: {{literalBehavior}}</div>' +
                  '<div>Result of behavior(): {{result}}</div>',
        link: function (scope) {
            scope.foo = scope.foo + " (modified by directive).";
            scope.result = scope.behavior();
            scope.call({ val: 99 });
        }
    }; });

With the following result:

image

To break down what is happening, I offer the following explanation that I hope will help to clarify how isolate scope works. Please note that although for the sake of illustration I’m using $scope, this works equally well with the controller as approach that I recommend.

Bindings

if your directive looks like this:

<my-directive target="foo" />

Then you have these possibilities for scope:

{ target: '=' }

This will bind scope.target (directive) to $scope.foo (outer scope). This is because = is for two-way binding and when you don't specify anything, it automatically matches the name on the inner scope to the name of the attribute on the directive. Changes to scope.target will update $scope.foo.

{ bar: '=target' }

This will bind scope.bar to $scope.foo. This is because again we specify two-way binding, but tell the directive that what is in the attribute "target" should appear on the inner scope as "bar". Changes to scope.bar will update $scope.foo.

{ target: '@' }

This will set scope.target to "foo" because @ means "take it literally." Changes to scope.target won't propagate outside of your directive.

{ bar: '@target' }

This will set scope.bar to "foo" because @ takes it's value from the target attribute. Changes to scope.bar won't propagate outside of your directive.

Behaviors

Now let's talk behaviors. Let's assume your outer scope has this:

$scope.foo = function(parm1, parm2) {
     console.log(parm1 + ": " + parm2); }

There are several ways you can access this. If your HTML is:

<my-directive target='foo'>

Then

{ target: '=' }

Will allow you to call scope.target(1,2) from your directive.

Same thing,

{ bar: '=target' }

Allows you to call scope.bar(1,2) from your directive.

The more common way is to establish this as a behavior. Technically, ampersand evaluates an expression in the context of the parent. That's important. So I could have:

<my-directive target="a+b" />

And if the parent scope has $scope.a = 1 and $scope.b = 2, then on my directive:

{ target: '&' }

I can call scope.target() and the result will be 3. This is important - the binding is exposed as a function to the inner scope but the directive can bind to an expression.

A more common way to do this is:

<my-directive target="foo(val1,val2)">  

Then you can use:

{ target: '&' }

And call from the directive:

scope.target({ val1: 1, val2: 2 });

This takes the object you passed, maps the properties to parameters in the evaluated expression and then calls the behavior, this case calling $scope.foo(1,2);

You could also do this:

<my-directive target="foo(1, val)" />

This locks in the first parameter to the literal 1, and from the directive:

{ bar: '&target' }

Then:

scope.bar(5)

Which would call $scope.foo(1,5);


Summary

As you can see, scope isolation is a very powerful mechanism. When used correctly it enables you to reuse a directive and protect the parent scope from side effects, while allowing you to pass important attributes and bindings as necessary. Understanding this will be a tremendous benefit for you when authoring custom directives.

As always, your thoughts and feedback are appreciated!

signature[1]

Tuesday, May 19, 2015

AngularJS Project Essentials

You’ve read the tutorials, watched the online demos and wrote the to-do list app in Angular. Now you’ve been assigned your first real world project. You create the project, hook in Angular, and start coding away.

“Now what?”

After over three years of writing Angular enterprise apps, I’ve found there are a few elements I almost always pull in. I hesitate to call these “best practices” because they are common but not universal, and they are too small to really justify releasing as part of a stand-alone module, so I’ve gathered them here in a single blog post to share with you.

An ng-View to a Kill

When you write apps that fetch large amounts of data or that load dozens of components, it quickly becomes clear the user experience isn’t as clean “out of the box” as you might want it to be. If you’ve seen the “flicker” caused by rendering a screen full of moustaches you know what I mean. There is no reason the end user should ever have to see:

{{model.foo}}

Flicker briefly before turning into some text.

Angular provides ngCloak as a way to manage this, but I’ve found an even more straightforward approach. Most of my projects include Bootstrap which has a nice set of styles for showing and hiding portions of the UI. Although I preach the use of controller as I’m not opposed to using the $rootScope goo that makes a nice cork board to pin UI behaviors on.

Take a look at this approach:

<div class="container body-content hide"  
        ng-class="{'show': loaded}" 
        ng-init="loaded=true" 
        ng-app="myApp">

The content is rendered as hidden out of the gate. A conditional class to show the content is applied based on a variable that will only exist once the application is initialized. It’s simple, clean, and doesn’t require testing or exposing strange controller methods just to handle a common UI behavior.

Animations for the Design-Challenged

I’m not much of a designer or animator. I make an effort to keep up to date and consistently force myself outside of my comfort zone, but I’m a long way from architecting my own master CSS or creating a super cool animation from scratch. That’s why I’ve made friends with two cool libraries. The first, part of Angular, is called ngAnimate.

Apparently there is a lot you can do with this, but I stop at including it as a dependency. That’s because I also depend on my other friend, animate.css. With a little bit of my own CSS, I can introduce the two to each other and implement all of the transitions I would ever care to use.

Here’s two examples that I crafted in my custom CSS to layer on top of the built-in styles that Bootstrap provides.

div[ng-view].ng-enter {
    -webkit-animation: zoomIn 0.1s, pulse 0.5s;
    animation: zoomIn 0.1s, pulse 0.5s; } .alert.ng-enter {
    -webkit-animation: slideInUp 0.3s;
    animation: slideInUp 0.3s; }

The first zooms and pulses new pages when the user navigates using Angular’s built-in router, and the other causes alerts to magically slide up to their position. You get the point – by starting with Angular’s classes, you can combine them with animations that will fire either globally or locally depending on how they are defined. The animations site itself is a great way to test and vet which animations you wish to use.

Give your Elements a Hand

While you’re in your CSS you might as well add this one.

.cursor-hand {
    cursor: pointer;
    cursor: hand; }

Have you ever bound an ng-click directive to an element that isn’t normally a link? Isn’t it weird that the cursor doesn’t change when you hover over it? Apply the cursor-hand class and it will show a nice little indication that it’s clickable, just like buttons and links do.

The Title is Yours

Have you ever found yourself running the same SPA application in multiple tabs, only to find navigation is a nightmare because they all have the same title? Give yourself, and your users, a break and update the title with context.

Here’s a tip: avoid the temptation to prefix the title with your app’s name. Your users know they are using it and don’t need the reminder. When most browsers become cluttered with tabs, the tabs shrink and you end up only seeing the app name portion of the title. Instead, put the most specific information first and if you like, append the title to the end.

Instead of:

My Bodybuilding App | Exercises | Inverted Squat

Try:

Inverted Squat | Exercises | My Bodybuilding App

I also like to use a service for this. That way I can mock it for tests, but easily change the application name in one place or even enhance the service to log consumption. This is what I end up with in most projects:

function service($window) {
    this.$window = $window;
    this.currentTitle = $window.document.title; } angular.extend(service.prototype, {
    setTitle: function(title) {
        var titleToSet = title + " | The Best App Ever";
        this.$window.document.title = titleToSet;
        this.currentTitle = titleToSet;

    } }); app.service("titleSvc", ["$window", service]);

Feel free to use it in your own (by the way, I call this from the constructor but also whenever the context in a controller changes).

Getting Busy

Everyone likes a busy indicator, right? I usually create a modal dialog using bootstrap right at the top of my application:

<div class="modal modal-backdrop" ng-class="{ show: isBusy }">
    <div class="modal-body">
        <div class="row center-block text-center h1">
            Give me a minute, OK?
        </div>
    </div> </div>

Next, I create a service. What’s nice is the service will work across multiple requests, so if you are waiting on three services it will stay activated until the last one completes. Each component just calls setBusy() to kick things off and resetBusy() when ready. It also has a slight delay built in so you don’t get flicker when the service loads quickly.

function service($rootScope, $timeout) {
    this.$rootScope = $rootScope;
    this.$timeout = $timeout;
    this.$rootScope.isBusy = false;
    this.busyCount = 0; } angular.extend(service.prototype, {
    setBusy: function () {
        var that = this;
        this.busyCount += 1;
        this.$timeout(function() {
            that.$rootScope.isBusy = !!that.busyCount;
        }, 300);
    },
    resetBusy: function() {
        this.busyCount -= 1;
        this.$rootScope.isBusy = !!this.busyCount; 
    } }); app.service("busySvc", ["$rootScope", "$timeout", service]);

Because I also like to save myself keystrokes, instead of calling this every time I am waiting on a web service, I simply plug it in globally using interceptors.

app.config([
    "$provide", "$httpProvider", function (provide, httpProvider) {
        provide.factory("busyInterceptor", ["$q", "$injector", function (q, injector) {
                var getService = function() {
                    return injector.get("busySvc");
                };
                return {
                    request: function(config) {
                        getService().setBusy();
                        return config || q.when(config);
                    },
                    response: function(response) {
                        getService().resetBusy();
                        return response || q.when(response);
                    },
                    responseError: function(rejection) {
                        getService().resetBusy();
                        return q.reject(rejection);
                    }
                };
            }
        ]);
        httpProvider.interceptors.push("busyInterceptor");
    } ]);

Then I rarely have to call it explicitly.

A Dirty Little Trick

Almost every app ends up with some complex form that has dozens of fields to fill out. No user wants to spend ten minutes filling out a form only to accidentally close the window or navigate away. I handle this scenario with a directive. The directive allows me to bind to whatever trigger should prompt the user before navigating. In most cases that is the state of a form, but the beauty of Angular and data-binding is that you can use whatever you like, whether it is an expression or a custom property you expose.

Here is the directive, complete with the code to clean up after itself when the user does navigate away:

app.directive('dirtyChecking', [
    '$rootScope', '$window', function (rs, $window) {
        return {
            restrict: 'E',
            replace: true,
            template: '<span></span>',
            scope: {
                dirty: '='
            },
            link: function (scope) {
                var cleanUpFn = angular.noop, unwatch,
                    checkScope = function() {
                    if (scope.dirty) {
                        cleanUpFn = rs.$on('$locationChangeStart', function(event) {
                            if (!$window.confirm('You have unsaved changes, do you want to continue?')) {
                                event.preventDefault();
                            }
                        });
                    } else {
                        cleanUpFn();
                        cleanUpFn = angular.noop;
                    };
                }
                unwatch = scope.$watch('dirty', checkScope);
                scope.$on('$destroy', function() {
                    cleanUpFn();
                    unwatch();
                });
            }
        }
    } ]);

And here it is in use:

<div ng-controller="myCtrl as ctrl">
    <form name="ctrl.myForm" novalidate="">
        <dirty-checking dirty="ctrl.myForm.$dirty">
        </dirty-checking>

It’s a dirty little trick but it works well!

You’ve Been Alerted

The final pattern I implement in most apps is notifications or toasts. Bootstrap provides some very helpful classes for these. I typically create a simple service that hosts an array of alerts, then provides methods to add different types of alerts. I’ll leave the implementation up to you, but here’s where the tip comes in: in some cases you might be alerting an error when what you really want is to throw an exception. With a little configuration, you can intercept errors and alert on those as well. You can safely throw a new Error(“Oops!”) and know the user will get feedback because you’ve taken over.

This one is easier to show, so you can run it and view the source here. Note the use of the property getter to refresh the alerts from the controller without having to rely on $scope or using a $watch. In this case I’m passing the exception along to the default handler, but I could easily just swallow it in my replacement function as well.

Want more advanced tips and tricks like this? Read my series The Top 5 Mistakes AngularJS Developers Make for more!

That’s it for me. I’m sure many of you reading this also have common snippets you use. Feel free to reply to the comments here to share your ideas, and as always your feedback and suggestions are welcome!

signature[1]