Angular 1.3x Makes ARIA Enhancement Simple With ngAria Module

AngularJS No Comments »

One of the JavaScript podcasts I listen to mentioned that the one of the new features in Angular 1.3x was the ngAria module.  I knew just from the name that the module had something to do with ARIA (Accessible Rich Internet Applications) but I wasn't sure what it did or how to implement it, so I decided to check it out.

Turns out using this new module is drop-dead simple.  You don't have to add any code to your markup in order to use it:  once you include the ngAria module in your Angular application, it'll automatically add and manage "aria-" attributes on your DOM elements, attributes that help screen readers understand what's going on in your application.

The folks over at Egghead.io have an excellent five minute video that demonstrates ngAria in action:  https://egghead.io/lessons/angularjs-using-ng-aria-to-automatically-improve-your-angularjs-accessibility

You can also read more about ngAria on the AngularJS documentation page on accessibility:  https://docs.angularjs.org/guide/accessibility

Frankly, I can't see a reason for not including this module in your AngularJS application if you're using Angular 1.3x.  It won't solve every accessibility issue, but it's a good starting point.

 

 

Using the "Controller As" Syntax With AngularJS Controllers

AngularJS , JavaScript No Comments »

I recently had a chance to try out the "controller as" alternative to storing model data and controller functions on the $scope of an Angular controller, and I was rather taken with the elegance of it.

An example of the familar method of attaching a controller to a view via the regular Angular router and exposing data and methods via the $scope:

Route:

...
when('/auth/sales/salesPage', {
  templateUrl: 'views/sales.html',
  controller: 'salesController'
})
...

 

Controller:

.controller( 'salesController', [ '$scope', 'demoService',  function( $scope, demoService ) {
   $scope.uiState = { pageLoaded: false };

   $scope.performAction = function() {
     console.log( "Action!" );
   }
 }]);

 

View:

<h1>Sales Prospects</h1>
<div ng-show="uiState.pageLoaded"></div>

 

...now the same code but using the "controller as" methodology:

 

Route:

...
when('/auth/sales/salesPage', {
  templateUrl: 'views/sales.html',
  controller: 'salesController as vm' //'vm' is now a reference to the controller object
})
...

 

Controller:

.controller( 'salesController', [ 'demoService',  function( demoService ) {
   var vm = this; //The controller object takes the place of the scope.
   vm.uiState = { pageLoaded: false };

   vm.performAction = function() {
     console.log( "Action!" );
   }
 }]);

 

View:

<h1>Sales Prospects</h1>
<-- The route provides the controller object to the view as 'vm' -->
<div ng-show="vm.uiState.pageLoaded"></div>

 

Some of the benefits of this "controller as" methodology:

  • You don't have to inject the $scope into the controller.
  • If you have multiple views with multiple controllers on the same page, you can now have unique references/namespaces for each controller and not worry about name collisions between each controller's $scope.
  • It looks cleaner.
  • Less typing of "$scope" means you won't wear out the 4/$ key on your keyboard as quickly. :)

 

Task-based web browsing: Grunt and the grunt-open plugin

JavaScript , Miscellaneous No Comments »

Lately I've been playing around with Grunt, which is a JavaScript-based task runner similar to Ant and Gradle. Generally, these tools are used to automate software builds, but they can be utilized in other ways.

While browsing through the large collection of Grunt plugins, I came across one called grunt-open. The grunt-open plugin lets you create a task that opens a URL in your web browser. It looks like it was created with the idea of opening a web page at the end of a chain of Grunt tasks to check the result of a software build. But I thought it might be useful in automating everyday web browsing tasks.

I like to start off my work day with a bit of Internet humor and I have certains sites I visit for that. Dilbert has a new strip every day, while JoyOfTech and XKCD get published every Monday, Wednesday, and Friday, and the XKCD "What-If" article is published once a week, usually by Thursday. Rather than manually opening the appropriate bookmarks for the appropriate day of the week, I figured I'd program a task to take care of opening the appropriate sites.

I won't reinvent the wheel here trying to explain the basics of Grunt: the Grunt "Getting Started" guide does a good job of explaining how to install Grunt and generate the files needed (the package.json and the Gruntfile.js files). Here's what my Gruntfile looks like:

 
module.exports = function( grunt )
{
    grunt.initConfig({
        open: {
            joyoftech: {
                path: 'http://www.geekculture.com/joyoftech/',
                app: 'Chrome'
            },
            dilbert: {
                path: 'http://www.dilbert.com/',
                app: 'Chrome'
            },
            xkcd: {
                path: 'http://www.xkcd.com/',
                app: 'Chrome'
            },
            xkcdwhatif: {
                path: 'http://what-if.xkcd.com/',
                app: 'Chrome'
           }
        }
    });

    grunt.loadNpmTasks( 'grunt-open' );

    grunt.registerTask( 'webhumor', 'Load the funnies!', function() {
        var today = new Date();
        var dayOfWeek = today.getDay();

        switch( dayOfWeek ) {
            case 1: //Monday
            case 3:
            case 5:
                grunt.task.run( [ 'open:joyoftech', 'open:dilbert', 'open:xkcd' ] );
                break;
            case 0:
            case 6:
            case 2:
                grunt.task.run( [ 'open:dilbert' ] );
                break;
            case 4:
                grunt.task.run( [ 'open:dilbert', 'open:xkcdwhatif' ] );
                break;
        }
    })
};

So in the directory where this Gruntfile.js lives, I just have to type "grunt webhumor' in the command, and Grunt will open the appropriate sites. Not a huge timesaver, but kinda cool.

On Today's Experience Installing Ionic for Android Development (on Windows 8.1)

Miscellaneous No Comments »

This is one of those posts that's likely to become obsolete very quickly as the install process for Ionic changes, but if it helps someone else resolve the (minor) install issues I ran into today, then it's worth doing.

The installation instructions that start at http://ionicframework.com/docs/guide/installation.html are pretty good considering the number of technologies involved in getting up and running (npm, the Java JDK, the Android SDK, Cordova, etc.).  But as those technologies changes so does the install process, even if the change is slight.

The first issue I ran into occurred when I tried to run the "ionic start" command from the command line.  I got a two-part error message in the console.  The latter message, cast in red text, suggested that my version of Cordova was outdated:  not likely since I'd installed it 30 minutes ago.  The earlier message said "could not create work tree dir" and cited a nested folder under my user account folder called "plugman".  Fortunately, someone had posted the solution (the need to create the missing directory) in the Ionic forums:  http://forum.ionicframework.com/t/unable-to-add-plugins-perhaps-your-version-of-cordova-is-too-old/3807/10.

The next issue came up at the conclusion of the install process when I tried to run "ionic emulate android".  Again, the final error message wasn't that helpful; the earlier message stated that "abd" was not recognized as a command.  The reason that happened was because the instructions say to declare the ANDROID_HOME Path variable to point to the "tools" directory of the Android ADT bundle, but Google moved the adb executable from the "tools" directory to the "platform-tools" directory (they left a note in the tools directory about the move).  For Ionic to work you actually need pointers to both the "tools" and "platform-tools" directories in the path.

The last issue was particular to my machine.  I had a pre-existing Android Virtual Device (AVD) configuration from an earlier install of the Android Eclipse plugin, and when Ionic tried to use that AVD it complained that a kernel file was missing.  I ended up launching the AVD manager from the command line ("android avd") and using the "Repair" option to repair the AVD, and that apparently fixed the problem, and the emulator opened at its typical glacial pace.

 

Object Equivalency and Select Options in AngularJS ("Why Isn't the Correct Option Selected?")

AngularJS 1 Comment »

In my last blog post, I talked about the angular.equals() function in AngularJS and how it compares two JavaScript objects for equivalency based on the properties and property values of each object.  Angular provides that function because in JavaScript, object1 == object2 is only true if object1 and object2 are both pointers/references back to the same object in memory.

This default "equivalency by reference" can cause some counter-intuitive behavior at times.

Read more...