AngularJS ‘service’ goes from being the red headed step child to the golden child

I have a confession to make, I did not have a single service that was created and registered using service in my massive AngularJS app before migrating to ES6. They were mostly created using factory and where appropriate, created using provider – but not a single one with service. I just preferred how factory felt and looked. Providers, though verbose, were the only way to make a service configurable. Surprisingly, I found that I wasn’t the only one in this conspiracy against services. In fact, I have read multiple blog posts where people have outright dissed services and recommended using factory.

Through my journey migrating this same app to ES6, my feelings to this often neglected style have changed. It has become my go to approach now. Why you say this change of heart? Well, it is because ES6 classes lend themselves very well to services. They plug right in. This is also how I create controllers. I like this idea of being able to follow the same pattern to create controllers and services. I wish I could create directives the same way but unfortunately it needs be a function that returns a directive definition object.

export class Security {
  constructor() {
    this._permissions = ['deleteUsers'];
  }

  get username() {
    return "Don Joe";
  }

  isAdmin() {
    return true;
  }

  checkAccess(permission) {
    return this._permissions.find(perm => perm === permission);
  }
}

This class can be simply plugged into the service registration function:

import {Security} from "security";

var app = angular.module('plunker', [])
            ....
            .service('security', Security)
            ......

With all the news post ng-europe about AngularJS 2.0 and how everything is going to be built around ES6 classes and modules, I am hoping that this approach would leave me in a better place when it is time to migrate over to AngularJS 2.0. I am not going to be naive and expect it to be smooth migration, but I am hoping that these tiny steps today will alleviate some pain in the future. Hopefully my classes will be directly pluggable into whatever the equivivalent or replacement for services will be (if any) or maybe it will be as simple as just adding the appropriate annotations to my existing classes so that they act like controllers or services. Fingers crossed.

Here is a working plunk

Creating AngularJS Controllers in ES6

I am currently in the process of migrating one of our apps (previous post) to ES6 and here are a few ways I learnt to create AngularJS controllers in ES6.

Inject a $scope into a function and then tack on properties and methods like I always did (before Controller As) but this time with some ES6 goodness:

export let ScopeInjectedCtrl = function($scope) {
  $scope.msg1 = "Hi from ScopeInjectedCtrl";

  $scope.updateMsg2 = function() {
    $scope.msg2 = "Hello! from ScopeInjectedCtrl";
  }
}

Inject a $scope into an anonymous function and tack on properties and methods. This approach is just a shorthand for the above. Being an anonymous function, this has to be declared right where the controller is created.

app.controller('ScopeInjectedAnonymousCtrl', $scope => {
    $scope.msg1 = "Hi from ScopeInjectedAnonymousCtrl";

    $scope.updateMsg2 = function() {
      $scope.msg2 = "Hello! from ScopeInjectedAnonymousCtrl";
    };
  });

And finally, my favorite – pure ES6 classes with methods, getters and setters. This pairs very well with Controller as syntax.

export class PureClassCtrl {

  constructor() {
    this._msg1 = "Hi from PureClassCtrl";
    this._msg2 = "";
  }
  get msg1() {
    return this._msg1;
  }

  get msg2() {
    return this._msg2;
  }

  updateMsg2() {
    this._msg2 = "Hello! from PureClassCtrl";
  }
}

The pure class style feels very clean (to me personally), just like the current Controller As does. However, remember that the same rules apply as today’s Controller As syntax when it comes to adding a $watch or dealing with events using $on, ‘$emit’ or $broadcast – the $scope will need to be injected – so method 1 or 2 are going to be better options (unless there is a better way of handling it with class that I am not aware of).

A plunk that shows the above mentioned ways of creating controller here

AngularJS and ES6

I was working on refactoring some of my Javascript code for an Angular app when I decided that I would convert most of my client side code to ES6 so that I am ahead of the curve come AngularJS 2.0. I have begun taking baby steps in this direction but information is hard to come by at the moment on using ES6 with AngularJS. I ran into a major hurdle before I could get my rudimentary HelloWorld app running and that is what instigated me to write this post (finally a post after 3 years). Hopefully it will help someone out.

The interwebs tell me that recommended way to get up and running with ES6 is to use Traceur. The GitHub page has a handy Getting Started guide but if you are interested in learning more about ES6 I would highly recommend watching this fantastic little course on Pluralsight called Javascript Fundamentals – ES6 by Scott Allen and Joe Eames.

Without going into too many details – Traceur lets you transpile your ES6 code into ES5 so it can be used in the current browsers. You can traspile either on the fly by directly referencing the following traceur libraries in your web page and setting some flags:

<script src="https://google.github.io/traceur-compiler/bin/traceur.js" data-require="traceur@*" data-semver="0.0.0-20140302"></script>
<script src="https://google.github.io/traceur-compiler/src/bootstrap.js" data-require="traceur@*" data-semver="0.0.0-20140302"></script>
<script>
      traceur.options.experimental = true;
</script>

or by transpiling the files offline using the traceur command line tool and then referencing the transpiled files in your HTML:

traceur --out app.js --script app.es6.js

After all the reading and watching, I thought i’ll write a plunk real quick to test this out. I decided I’ll create a class for my controller:

//MainCtrl.js
export class MainCtrl {
    get name() {
        return "World!!!";
    }
}

Import it where I am setting up the Angular module and create the new controller from my imported class

//app.js
import {MainCtrl} from "MainCtrl";

var app = angular.module('plunker', [])
.controller('MainCtrl', MyClass);

Bootstrap Angular:

<html ng-app="plunker">
</html>

Add a reference to my module in a script block:

<script src="app.js" type="module"></script>

That’s it (or at least that is what I thought), hit Run and …

Error: [$injector:nomod] Module 'plunker' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument. 

Plunker

I wrote the same code locally on my machine, transpiled it offline, concat-ed them and reference a single file in my html and everything worked. However, I was just not able to do the same on the fly. It turns out I needed to jump through some hoops before I could get it working. It turns out that the

<script type="module"></script>

polyfill runs asynchronously so initializing Angular can be a little tricky.

The good fellows watching the Traceur Github issues helped me quickly figure out what was going on. I had to block the initialization of Angular until after the module evaluation and would have to bootstrap Angular manually, like so:

<script>
      System.import("app").then(function(a){
        angular.element(document).ready(function() {
          angular.bootstrap(document, ['plunker']);
        });
      });

</script>

Plunker

That’s it. I had my Hello World app built on top of ES6 running.

Now that I have Angular bootstrapped and running, I intend to explore how to go about taking the most advantage of ES6.

Abhorred Calendar

GitHub repo

Question: What kind of bear is best? Why did I name my very first, super slick jQuery plugin Abhorred Calendar and not big pimpin’ calendar?

Answer: Thanks to the idea (and the time consuming process) of entering time, this has quickly become one of the most hated sites in our team; hence the name. We devs rather code away all day, catch up on some blogs, maybe sports scores or even get up to speed with the “Most Viewed” you-tube videos of the day; heck, we would rather comment our code than enter time. I for one am guilty of that. However, in my defense, I am sure my teammates will vouch for me when i say this process is like a billion gazillion times better than what we had before was, to be subtle, pre-historic.

A little bit of history on how this came to be (please feel free to skip over this if your tech-voracity is getting the better of you): The very first incarnation of this time entry tool and it’s befitting reports happened in Silverlight. Our upper management fancied themselves some iPads, so I thought it would be cool if our VPs, Directors and the likes could get to these reports from their new toy and a few of our snazzy employees could enter time from their new tablet/smart-phone. Web standards to the rescue!!!

Since this was my first time with a whole set of new technologies, my first approach was to build html for the entire calendar on the server side in C# and load the it up using jQuery AJAX helpers on the client upon clicking certain buttons. As I got comfortable with JavaScript, jQuery and HTML (read my previous post for an understanding of where I come from), I decided to get rid of the unnecessary AJAX call to build the calendar and decided to go with a pure client side implementation – Hello Abhorred Calendar!!!!

Alright, enough of this B.S!

As of this writing, these are the features my plugin provides. Please feel free to Fork it.

Non-themed

Themed using jQueryUI

Themed

  • jQueryUI theming support
  • Use Arrays or JSON data to populate calendar
  • Use provided CSS or roll your own (would love to see what you come up with. Please “Fork” the repo and I will try to “Push” whatever I think is appropriate)
  • Can be customized to most time entry scenarios

Initialization is as simple as:

$('#container').abhoredCalendar();

If you want to take some action when the user clicks the “+” (Add) button you will need to provide a callback function as follows:

$('#container').abhoredCalendar({ addButtonClicked: addButtonCallback});
... function addButtonCallback() { alert('This is coming from the add button callback. You clicked: ' + $(this).attr('id')); }

If you want the Calendar to be populate with something meaningful you can pass some data to the initializer in the form of the “data” parameter. The “data” parameter is JSON data in the following form:

{ date : hours }

Dates with no hours can be skipped.

Sample JSON Data:

var data = {"1": "2","5": "10", "17":"4"};

2 hours for the 1st of the month, 10 hours for the 5th of the month, 4 hours for the 17th of the month…… you get the idea.

You can call the “setData” method at any time to update the data on the calendar:

 $('#container').abhoredCalendar.setData(data);

A callback (monthChanged) can be provided which will execute everytime a user clicks “previous month” or “next month” button. This is where you would either hard-code some data or more realistically make an AJAX call to get the data for that particular month.

//CALLBACK function
 var data = {"1": "2","5": "10", "17":"4"}; $('#container').abhoredCalendar({ monthChanged: doMonthChange, data: data }); .......... function doMonthChange(date) { //make AJAX call to get data and pass it to the "setData" function $('#container').abhoredCalendar.setData(data); }

If and when new features are added to this project, I will update this post so that it remains as the main source of documentation for this project.

For complete code, check out Index.html on GitHub.

A big, bold move into the world of web standards!

HTML5

So after developing software for about 10 years and wanting to write a technical blog for 5 of those, I finally decided to wet my feet.

My recent exploits with MVC drove me to finally start blogging – or document my journey into this fascinating world of web standards. I attribute this baptism to MVC and my new-found passion for front end development. Before MVC, I mindlessly dropped controls on my forms never worrying about what & how ASP/ASP.Net worked behind the scenes to convert them into valid HTML elements. To my credit, I considered myself more of a business logic guy and loved (and still do) what I did. By no means am I a designer now, hell no. I still think from the left side of my brain, but off late I have been pushing myself to use at least an iota of my right. Let me tell you its rusty, it creaks every time I exert it.

I personally think that the right lobe activity starts early in one’s life and maybe I’m a little too old to try to jump-start my creative and imaginative side, but I also think that one doesn’t need to think from their right brain to be a good web designer; GREAT designer – most definitely (At least this is what I have led myself to believe to keep me going).

I have been developing exclusively in C# all my life with some C, C++ and a boat load of other languages during my Bachelors and Masters (which I should say, I never ever used in my life, LISP anyone??). Adopting MVC mandated coding in pure HTML and JavaScript. After being a little apprehensive in the beginning, I have grown to love this new world of Web Standards, HTML 5 & CSS 3, finally grasping what all this rave was about, this whole new world, no this microcosm of open source plugins developed on top of libraries like jQuery, Prototype, etc and the juggernaut called GitHub.

So to initiate this journey, I am going to blog about my very first jQuery plugin and how I plan to make it open source and host it on GitHub for people to freely use my work and hopefully enhance it and help me learn through this process.

I don’t know which direction this is going to go, if my passion for web designing will still be alive in a year or if I have moved on….

So here goes……