Writing Good Angular Code

By Cameron Wilby

We’re big fans of John Papa at Origin Code Academy. The work that he and the Angular community have put into writing style guides not only for Angular 1.X, but also for the upcoming 2.X release is awesome.

Personally what I like about the guide is that lots of the style points come from real world experience, written from a point of view where readability and maintainability are king, because complex software is rarely written written in a vacuum. There are often many developers working on a single project, and with the rising salary of keeping good talent on your team – ensuring that they are able to be efficient and enjoy the work they do is paramount to providing value to a software solution.

I’ve included and paraphrased a few of my favorite style points below.

Write “Singularly Responsible” Angular components.

Follow the Rule of 1 principle, which states you should define 1 component per file, recommended to be less than 400 lines of code. One component per file makes your code far easier to read, maintain and avoid collisions with teams using a source control solution like Git or Mercurial. It also helps to avoid hidden bugs that often arise when combining components in a file where they may share variables, create unwanted closures, or unwanted coupling with dependencies.

/* avoid */
angular
    .module('app', ['ngRoute'])
    .controller('SomeController', SomeController)
    .factory('someFactory', someFactory);

function SomeController() { }

function someFactory() { }
/* recommended */

// app.module.js
angular
    .module('app', ['ngRoute']);

// some.controller.js
angular
    .module('app')
    .controller('SomeController', SomeController);

function SomeController() { }

// some.factory.js
angular
    .module('app')
    .factory('someFactory', someFactory);

function someFactory() { }

Use a consistent naming convention for your Angular components.
Use consistent names for all components following a pattern that describes the component’s feature then (optionally) its type. A recommended pattern for you to follow is feature.type.js. There are 2 names for most assets.

The file name (checkout.controller.js)
The registered component name with Angular (CheckoutController)

There’s a running joke in the industry that there are only 2 hard things in software development. Cache invalidation, and naming things. Naming conventions help provide a consistent way to find content at a glance. Consistency goes a long way to help your project, team, and company provide tremendous efficiency.

Wrap Angular components in an IIFE.
Now that we’ve talked about keeping Angular components in separate files, let’s talk a little bit about how those files should be laid out. Wrap the entire file in an IFFE (Immediately Invoked Function Expression). This ensures that variable and function declarations do not live longer than expected in the global scope, which helps to avoid naming collisions with other libraries. It also allows you to utilize the “use strict” declaration without affecting third-party components that may not utilize “use strict”.

(function() {
    'use strict';

    angular
        .module('app')
        .controller('CustomerController', CustomerController);

    function CustomerController() {        
    }
})();

Keep data calls in a factory, not in the controller.
You should keep logic for making data operations and interacting with data in a data service, contained in an Angular factory rather than in an Angular controller. Make data services responsible for XHR calls, local storage, stashing in memory or any other data operation you can think of, and inject those into your Angular controller.

The controller’s responsibility is for the presentation and gathering of information to/from your HTML. It should not care how it gets the data, just that it knows who to ask for it. This will not only simplify the code in your controllers, but also make it easier to unit test your controllers by being able to pass in a mock data service, which is simpler than mocking the $http service.

/* recommended */

// dataservice factory
angular
    .module('app.core')
    .factory('dataservice', dataservice);

dataservice.$inject = ['$http', 'logger'];

function dataservice($http, logger) {
    return {
        getAvengers: getAvengers
    };

    function getAvengers() {
        return $http.get('/api/maa')
            .then(getAvengersComplete)
            .catch(getAvengersFailed);

        function getAvengersComplete(response) {
            return response.data.results;
        }

        function getAvengersFailed(error) {
            logger.error('XHR Failed for getAvengers.' + error.data);
        }
    }
}

Write minification-safe Angular components.
Minification is the act of compressing client code delivered by a server so that the file size is lower. If you have a lot of user load on your web application, this will help your server handle more requests with fewer resources. For Angular code to be correctly minified, avoid using the shortcut syntax of declaring dependencies without using a minification-safe approach like this:

/* Original Code */
angular
	.module('app')
	.controller('DashboardController', DashboardController);

function DashboardController(common, dataservice) {
}	

Instead, you should manually identify dependencies using $inject. This is the most readable way to manually declare dependencies for an Angular component.

/* Original Code */
angular
	.module('app')
	.controller('DashboardController', DashboardController);
	
DashboardController.$inject = ['$location', '$routeParams', 'common', 'dataservice'];
	
function DashboardController($location, $routeParams, common, dataservice) {
}

Don’t use $scope, use the Controller-as syntax.
Controllers are constructed or “instantiated” when they are needed, and destructed or “deinstantiated” when they are no longer needed. The Controller-As syntax is closer to that of a JavaScript constructor than the classic method of injecting a redundant $scope service into your controller. It also promotes the use of binding to a “dotted” object in the View, which brings a greater sense of context, is easier to read, and avoids any and all scope inheritance issues that you may run into in the future.

// dashboard.controller.js
(function() {
    'use strict';

    angular
        .module('app')
        .controller('DashboardController', DashboardController);

    function DashboardController() {
        var vm = this;
        vm.title = 'DashboardController';
    }
})();

 

My Life as a Coder – Week 2

By Dangermin Field

As the title of this blog indicates, this is about my life, challenges, wins and goals as a coder, which I’m thinking about changing to “Developer”. I wish I could write in here everyday but one challenge any new developer in a bootcamp like Origin Code Academy will learn, is that time is one of those challenges.

It’s just ending the near of week two and we’ve already covered so much ground.  I mean we have really jumped into the deep end and I’m treading water as hard as I can to grow the muscles I need to swim.

I went to my 1st meet-up last night after having a really hard day with AngularJS and I have to say it was really a great experience.  I spoke with a lot of people from all levels of experience and told them about my struggles and listened to their stories and words of advice.

One guy I talked to that went to bootcamp in Seattle and was astonished when I told him we were learning Angular on day 7, his school didn’t even touch it till week 12 (their last week). And another student from a local school that was on his last week (week 12) had never even heard of it.  This made me realize that by getting in deep now, I will have just that much longer to learn how to swim before I jump into the ocean of looking for work.

I’m proud that I shopped around and found the school that matched my learning style and needs.

To anyone out there thinking about going to a code bootcamp, I can’t emphasize enough to find one that fits.  It’s going to be long nights no matter where you choose, so make it worth it!