Posts tagged AngularJS
Addition to AngularJS Component Refactoring Presentation

After creating my initial AngularJS Component Refactoring presentation, which explained how to refactor your Angular 1.x apps to use component-based design, there were some new developments in Angular that fit nicely as a next step. Angular 1.5 was released, which added a component function that is basically a more simple form of a directive like we refactored to in the presentation.

Angular 1.5 adds a logical next step for us to get to a component based design, and even closer to making an upgrade to Angular 2 much easier.  Angular 1.5 also adds a one way databinding type, but it doesn't work exactly like I hoped, I covered that in the updated presentation, too.

I updated my slides that I used during the presentation at the March Boise Frontend Developers Meetup.

AngularJS 1.x Component-based Design

With all the talk about Components being the future of the web, and frameworks like React and Angular 2 using them so prominently, why do we have to wait? Why can't we start refactoring our Angular 1.x apps right now to use the new design practices in these up an coming frameworks? Well, we can take some baby steps towards refactoring our Angular 1.x apps to take advantage of a Component-like design.

I gave a presentation about this topic at the Boise Frontend Development meetup in February.  You can get the slides here.

The presentation has links to three separate code demos, all hosted on Plunker.

Jeremy ZerrAngularJS, Javascript
AngularJS Promises Presentation and Demo Code

I made a promise to present about AngularJS promises to our Boise AngularJS Meetup, and I resolved that promise. (sorry for the bad attempt at programmer humor)

Here is a link to the presentation slides as a PDF.

Included in the presentation were three separate Plunkers showing different variations of implementing an Image Preloader to show how to use several features of AngularJS promises.

Jeremy ZerrAngularJS, Javascript
Using AngularJS ui-router Query Parameters and Complex Directives Together Without Killing App Performance

This is a presentation that I gave at the Boise AngularJS meetup.  The Plunker that goes along with this can be followed along with here.

The Problem

You have an application where you want to allow the user to pan an image.  This is a large image which you cannot display on the screen at one time.  In this example, I'm using the AngularJS shield logo, but a more pertinent example might be a geo-mapping application, or a data visualization application.  In an application like this, you may prefetch more data than is actually shown on the screen to be rendered quicker as the user performs a few fairly predictable actions (like moving it around).  Think of an application like Google Maps.  If you are looking at your city, you most likely are going to drag it around a little bit, because you might be travelling.  You might pre-fetch neighboring map images so that the drag feature would be able to be fast since you can almost predict it happening.

The other requirement is that the location within the image that the user pans to must be captured in the URL to allow permalinking to a particular view.  We want the user to be able to just copy and paste, or socially share, the URL in the address bar with friends.  This is also a lot like Google Maps, you can find your favorite barcade and email it to your buddies by clicking a share button or copy and pasting the URL.

With that requirement, your URLs will then look something like: /image?x=50&y=100

Where x and y represent the offsets into the image.  With a map, these would probably be latitude and longitude.

You initially implement this within ui-router as a single state with query args, like:

.config(function config($stateProvider) {
  $stateProvider.state('single', {
    url: '/single?x&y',
    controller: 'SingleCtrl',
    templateUrl: 'single.html'
  })
})

See the Plunker in the single.js file for this code.  Then in the Angular way, you decide to encapsulate the image loading and panning in a directive within single.html.  Like this:

<canvas my-image image="imageurl" x="navigation.x" y="navigation.y" width="400" height="400"></canvas>

You design your directive to be attached to a canvas element as an attribute, with directive attributes for the x and y position. Within the directive, you then load the image into memory which requires a fetch from the server, then write it to the canvas element within this directive.

When you start panning around, you notice that it is not very responsive.  There is a delay every time you switch the x and y coordinate.  You can see this within the Plunker when looking at the Single tab.  Use the Pan buttons to move the image around.  (For this exercise, I've added in a 500ms delay to simulate a delay in processing in a complex directive).

This is due to the fact that with ui-router, every time a query arg is changed, it is a state change, the controller is executed again, and the template is re-rendered.

The Solution

Follow the pattern of splitting your states with query arguments into two states, one for the "base" state, and a sub-state that handles the query arguments.

Your URLs will then look something like /image/view?x=50&y=100 as opposed to /image?x=50&y=100

The "base" state url is /image and the child state for the query parameters are /view?x&y.  Like:

.config(function config($stateProvider) {
  $stateProvider.state('double', {
    abstract: true,
    url: '/double',
    controller: 'DoubleCtrl',
    templateUrl: 'double.html'
  });
  
  $stateProvider.state('double.view', {
    url: '/view?x&y',
    controller: 'DoubleViewCtrl',
    template: '<div></div>'
  });  
})

You can see this in the Plunker in the double.js file.  Note: You cannot just have a child state of ?x&y, it does not work, must have a pattern to match on before the ?.

This allows the "base" state controller and template (which contains the directive) to stay as an active state and not be re-executed and re-rendered when just the URL query parameters change.

The fundamental difference between this two state and the single state example is that the query parameter handling code is pushed down into the child state, and changes the x and y inherited from the base state's scope, thus causing the directive to change.  Notice in the Plunker how the logic that was in the SingleCtrl is now split between DoubleCtrl and DoubleViewCtrl.  This actually leads to a very nice natural split in the functionality of the code, feels like better design.  All the query parameter handling logic to map back to an inherited parent navigation object that contains those same query parameters is in the DoubleViewCtrl which is the state with the query parameters in the URL.  Makes sense, right!

This "base" state can also most correctly be declared as abstract: true which means it cannot be transitioned to directly.

Now that the directive does not get re-created every time a query parameter changes.  It only changes the child state, not the base state.  This means you can just move the image around and copy to canvas very efficiently because it remains in memory.  Notice this by going onto the Double tab within the Plunker, you can see the execution count there, the parent state "double" controller and directive inside it's template only get called once.  Only the child state "double.view" controller gets executed with each click on the buttons.

Jeremy ZerrAngularJS, Javascript
AngularJS Backend-less Development Using a $httpBackend Mock

I was only able to briefly mention that I used a $httpBackend mock to do backend-less development with AngularJS during my presentation on AngularJS Data Driven Directives, so I created an isolated example in a Plunker to fully implement it.  Here is a link to the Plunker if you want to skip right there, below is an explanation and the embedded plunker.

The purpose of this example code is to show how to do backend-less development with code that uses both $http and $resource to fully cover the most common server communication options within AngularJS.

Why do backend-less development?

Isolating your AngularJS frontend development from the backend (REST API) can allow potentially separate teams develop independently.  Agreeing on the REST API can then allow both teams develop in parallel, agreeing to implement/use the REST service the same way.

This can be accomplished by the simple inclusion of a file in your AngularJS code that creates a mock using $httpBackend.  $httpBackend makes the requests that are underlying $http, which is also what ngResource $resource uses.  When you are ready to hit the real backend REST API, simple remove the file from being included, possibly as simple as a special task inside your grunt config.

There are two different flavors of the $httpBackend mock, we want to use the one not for unit testing, but for E2E testing:

AngularJS $httpBackend docs

How do we do it?

We use URL patterns within app-mockbackend.js to intercept the GET and POST calls to the URLs, along with the data for a POST.  We can use regular expressions as patterns, which allows for a lot of flexibility.

The handling of the URLs and HTTP methods and returning "fake" data only works by having some data that can be persistent from request to request.  I store the data in an AngularJS service ServerDataModel that emulates storing the data a lot like the server would.  The AngularJS service recipe is perfect for this becuase it injects a constructed object, and that object contains our data.  No matter where it is injected, the instance of the object is what is shared so it contains the same data.  There is some data that is pre-loaded in that object that is analagous to having a database on the server that already has some records.

Here is the embedded version of the code, although I do think it is easier to view in its full glory directly on Plunker.

AngularJS Data Driven Directives Presentation

Creating data visualization solutions in Javascript is challenging, but libraries like D3.js are starting to make it a whole lot easier. Combine D3.js with AngularJS and you can create some data driven directives that can be used easily within your web app.

I created a presentation for the Boise AngularJS Meetup to show how to design AngularJS directives that interact with D3.js.  Also, because there is no getting away from it, I also include some ideas on how to manage your data models and transform along the way to guarantee a logical separation from your domain data model and your chart data model.

The link to github for the code is: AngularJS Data Driven Directives

The code in that repository is up and running on my Github Pages site for this project with the demo located here: Basketball Scorebook demo page.

You can get at the slides here: AngularJS Data Driven Directives Presentation Slides