Monday, May 18, 2015

Week 8 - Promises

This week we will wrap up this series with the topic of promises (for some reason it took me awhile to get used to using this pattern; thus saving it for last).

Assignment
Fork the fiddle "AngularJS: A Walk-Through - Week 7" and
  • Name it "AngularJS: A Walk-Through - Week 8"
  • "Update" it and "Set as base". 

Assignment
Read articles describing promises; in particular:

JavaScript Promises and AngularJS $q Service
<http://www.webdeveasy.com/javascript-promises-and-angularjs-q-service/>

In order to demonstrate the $q service, we will refactor our gemService. First we refactor it so that has a query function with success and error callbacks (throwing in a 2 second timeout to introduce an asynchronous element).

JavaScript
 
// store/gems.service.js
(function() {
    angular
        .module('storeModule')
        .factory('gemsService', gemsService);
    /**
    * @name gemsService
    * @desc Service for gems.
    */
    gemsService.$inject = ['$timeout'];
    function gemsService($timeout) {
        var service = {};
        service.query = query;
        var gems = [{
            name: 'Azurite',
            // OBMITTED
            reviews: []
        }];
        return service;
        function query(success, error) {
            $timeout(function() {
                success(gems);
            }, 2000);    
        }
    }
})();   

With the new gemService, the StoreController is changed to:

JavaScript
 
// store/store.controller.js
(function() {
    angular
        .module('storeModule')
        .controller('StoreController', StoreController);
    /**
    * @name StoreController
    * @desc Controller for the store screen.
    */
    StoreController.$inject = ['gemsService'];
    function StoreController(gemsService) {
        var vm = this;
        gemsService.query(function(gems) {
            vm.products = gems;
        }, function() {
        });
    }
})();  

Now that we have a typical asynchronous function, we will rewrite the query function as follows with the $q service.

JavaScript
 
// store/gems.service.js
(function() {
    angular
        .module('storeModule')
        .factory('gemsService', gemsService);
    /**
    * @name gemsService
    * @desc Service for gems.
    */
    gemsService.$inject = ['$timeout'];
    function gemsService($timeout) {
        var service = {};
        service.query = query;
        var gems = [{
            name: 'Azurite',
            // OBMITTED
            reviews: []
        }];
        return service;
        function query() {
            var deferred = $q.defer();
            $timeout(function() {
                deferred.resolve(gems);
            }, 2000);
            return deferred.promise;
        }
    }
})();   

And now we implement the promise in the StoreController.

JavaScript
 
// store/store.controller.js
(function() {
    angular
        .module('storeModule')
        .controller('StoreController', StoreController);
    /**
    * @name StoreController
    * @desc Controller for the store screen.
    */
    StoreController.$inject = ['gemsService'];
    function StoreController(gemsService) {
        var vm = this;
        gemsService.query().then(function(gems) {
            vm.products = gems;
        });
    }
})();

Assignment
Using the information above, refactor this week's fiddle to use the $q service.

Sample of Week Result
The result of this week is an AngularJS app, "AngularJS: A Walk-Through - Week 8".

AngularJS: A Walk-Through - Week 8
<https://jsfiddle.net/sckmkny/e5LLpygs/>

Bonus
Now that one understands promises, the last refinement would be to change up the app so that the promises are resolved before loading the screen (to avoid showing the screen partially complete).  The key here is to AngularJS Route Resolves.

Using Resolves In AngularJS Routes
<http://odetocode.com/blogs/scott/archive/2014/05/20/using-resolve-in-angularjs-routes.aspx>

Saturday, May 9, 2015

Week 7 - Style Guides (Continued)

This week we will continue to refactor our code based on the opinionated style guide by Todd Moto.

Assignment
Fork the fiddle "AngularJS: A Walk-Through - Week 6" and
  • Name it "AngularJS: A Walk-Through - Week 7"
  • "Update" it and "Set as base". 

Assignment
Read through the last sections (starting from Filters) of the following style guide and apply fixes to the fiddle.  Some of the techniques are more advanced and thus not used in our simple example.

AngularJS StyleGuide by Todd Motto
<https://github.com/toddmotto/angularjs-styleguide>

Hints:
  • Routing resolves / Promises: We will address promises in a later week.
  • Performance / One-time binding syntax: Go through app to look for opportunities to use this feature.
  • Comment standards / jsDoc: Add some simple documentation to your app.

Assignment
Todd Motto suggests reading through another style guide; most of the ideas are duplicated.  Apply what is relevant.

angular-styleguide by John Papa
<https://github.com/johnpapa/angular-styleguide>

Hints:
  • Bindable Members Up Top (Y033) - Do it.
  • Manually Identify Dependencies (Y091) - Do it.
  • Routing (Y270) - Not using AngularJS Router in this example
  • Routing (Y271) - Move routing into separate files, e.g.
    • app.routes.js
    • marketing/marketing.routes.js
    • marketing/store.routes.js

Sample of Week Result
The result of this week is an AngularJS app, "AngularJS: A Walk-Through - Week 7" that will be used as a starting point for the next week.

AngularJS: A Walk-Through - Week 7
<http://jsfiddle.net/sckmkny/n1v22jjs/>

Sunday, May 3, 2015

Week 6 - Style Guide

This week we will refactor our code based on an opinionated style guide by Todd Moto that was suggested during the keynote speech of the ng-conf 2015 conference (AngularJS conference).  The main benefits of applying the style guide will be to make the code more supportable over the long-term.

note: Originally, was going to do this in one week, but due to the amount of changes, opted to break it into two.  Also, this week is a little different as it has less guidance (might require one to "cheat" and review the final result).

Assignment
Fork the fiddle "AngularJS: A Walk-Through - Week 5" and
  • Name it "AngularJS: A Walk-Through - Week 6"
  • "Update" it and "Set as base". 

Assignment
First, we are going follow a different (small) guide as to how to organize code into modules (and folders / files):

Code Organization in Large AngularJS and JavaScript Applications
<http://cliffmeyers.com/blog/2013/4/21/code-organization-angularjs-javascript>

Re-organize the fiddle into three modules (and folders / files) with each component in a separate file:
  • app
  • marketing (for the about components)
  • store (for the store components)
The final file structure (remember, we are using comments to delineate files in JSFIDDLE) ends up being:
  • app.js
  • index.html
  • marketing
    • about.controller.js
    • about.html
    • marketing.module.js
  • store
    • gems.services.js
    • product-description.directive.js
    • product-description.html
    • product-gallery.directive.js
    • product-gallery.html
    • product-reviews.directive.js
    • product-reviews.html
    • product-specs.directive.js
    • product-spec.html
    • product-tabs.directive.js
    • product-tabs.html
    • store.controller.js
    • store.html
    • store.module.js

Assignment
Read through the first four sections (Modules - Directives) of the following style guide and apply fixes to the fiddle.

AngularJS StyleGuide by Todd Motto
<https://github.com/toddmotto/angularjs-styleguide>

Hints:
  • Modules / Definitions: One will need to change up the fiddle to not use the setting and getter syntax.
  • Modules / Methods: One will need to change up the fiddle to pass functions into modules (rather than anonymous function callbacks).
  • Controllers / controllerAs syntax: Not much to do here as we did not use the older AngularJS binding with "$scope".  But, we do want consistent and unique names (instead of just "vm") in the "controllerAs" syntax; recommend something like "StoreController as storeVM".
  • Controllers / controllerAs 'vm': Need to use "vm" to capture the "this" context.
  •  Some other conventions to consider:
    • Modules are named lowerCamelCase.
    • Controllers are named UpperCamelCase (as they are constructors).
    • Factories are named lowerCamelCase.
    • Directives are named lowerCamelCase.

Sample of Week Result
The result of this week is an AngularJS app, "AngularJS: A Walk-Through - Week 6" that will be used as a starting point for the next week.

AngularJS: A Walk-Through - Week 6
<http://jsfiddle.net/sckmkny/xqy23z1e/>