notoriousb1t

MVP Part 2: AngularJS 1

For the last few weeks I have been building a project called Model View Pizza. It is a simple page that customizes a pizza and lets the user see it being built as each selection is made. I plan to build this same application in at least ten of the more popular JavaScript MV* frameworks in twenty weeks.


I decided to make the second framework AngularJS because it has a large community and is used by so many companies. Visual Studio Code has been my IDE of choice since the preview builds have been out. Code effectively uses TypeScript definition files to supplement their already intelligent auto-completion. AngularJS had such a definition, so it worked nicely in detecting the API for AngularJS.

What is AngularJS?

AngularJS is an MVC (Model View Controller) framework that facilitates separation of the html (View), the information/state (Model), and bundled logic and routing (Controller). Here is a simple diagram of what MVC looks like:

There seems to be quite a bit more to it in AngularJS, but I think that diagram gives a pretty good idea of how users initiate actions and in response, get a view to look at.

Getting Started

I love learning the basics by example. I have found that it beats reading documentation or following tutorials. Good documentation has a tendency to be, well... exhaustive. Good tutorials spend a lot of time laying the foundation for newcomers that I could spend actually building something. Good examples, however, can serve both as a form of documentation and as a tutorial. They act as documentation by providing usages. This helps me see how different parts of the API work together. They also act like a tutorial and only expose me to a few concepts at a time.

I was fortunate to find a good article that shows off the framework in five examples: Learn AngularJS With These 5 Practical Examples. Here some things I was able to deduce based on that article:

  • The ng-app attributes point to specific modules registered with AngularJS. This initializes that section of the page as the view.
  • The ng-controller attribute points to the controller that should handle the view. This is effectively the entry point to the application.
  • You don't call AngularJS, it calls you. The act of including the script in the page turns my webpage into an AngularJS application.
  • AngularJS includes a lot of binding functionality by default such as ng-click for binding click events, ng-model for binding to input elements, ng-show for displaying an element if the expression in quotations is truthy, etc.
  • Nested views are supported by the ng-repeat attribute. The syntax for these expressions reminds me a lot of C# LINQ's Query syntax or Python's list comprehension.

A Simple Example

Here is a super simple example of an AngularJS application:

See the Pen Angular + Bootstrap by Christopher Wallis (@notoriousb1t) on CodePen.

In the JavaScript, I registered a module named "app" to AngularJS. The module has one controller named "ButtonController". I used $scope to set fields to the model and to access instance methods of AngularJS. I initialized lights with a value of true and create flipSwitch to toggle lights on and off.

In the HTML, the properties lights and flipSwitch are setup to turn the lights on and off in the application.

Building the thing...

Design

I had the fundamentals down, so I decided to start building out the application. I looked back at my KnockoutJS project, but didn't really like the look and flow of it. Scrolling didn't feel intuitive and the use of Bootstrap was a bit heavy handed. I wanted to pare back the CSS and JavaScript use in the project, so I resolved to leave out Bootstrap for my AngularJS project.

Since I wasn't digging the design of the KnockoutJS version of Model View Pizza, I decided to pen a one-minute sketch of how I expected the new design to flow.

That wireframe may look like a bunch of scribbles, but it is enough to get the idea out of my head before I forget about it or over-analyze what I am trying to accomplish. The beauty of doing a quick sketch in pen is that I have to trust my instincts and draw whatever comes to mind. If I mess up, I scribble it out and move on. Here is a picture of what I actually built based on that sketch:

Development

The implementation of this project took me maybe four hours tops in development time. I was pleasantly surprised with how quickly I was able to translate my KnockoutJS code to AngularJS. Checkout the source code for the Model View Pizza: AngularJS project. While my productivity was exceptionally high, I do have a few issues with AngularJS.

Attributes Contain JavaScript

I can't deny that being able to put JavaScript directly in the attributes helped me get the project running quickly. In my experience however, putting logic in the view is rarely a desirable thing long term. Having that ability encourages a lack of separation of concerns. AngularJS is not the first framework to do this, but I would mark that down as a possible issue when working in a large team with less experienced developers. In this project, I have size == 'Large' in the code. If for some reason I changed Large to Mega, I would have to be very careful that I find all usages of the literal word. It is for this reason that this capability might be less than great.

It Feels like Magic

The registration code for modules and controllers feels like casting a magic incantation. At no point did I tell AngularJS to initialize against my views. I can't put my finger on exactly why that is disturbing, but it is nonetheless. I suppose that explicit initialization is something I value as a developer.

Overall Impression

I have never been more productive writing JavaScript. I think that AngularJS is a wonderful tool for prototyping and perhaps is great in production for teams with the right kind of leadership.

I am going to go back and redo the KnockoutJS application with the new design, and then move onto my next framework.