What You Need To Know About AngularJS Data Binding

You hear a lot about data binding in AngularJS, and with good reason: its at the heart of everything you do with Angular. I’ve mentioned data binding more than a few times in my guides to directives and filters, but I haven’t quite explained the internals of how data binding works. To novices, it seems like straight sorcery, but, in reality, data binding is fundamentally very simple.

Scoping out the situation

Fundamentally, data binding consists of a set of functions associated with a scope. A scope is an execution context for the expressions you write in your HTML. AngularJS scopes behave like scopes in Javascript: a scope contains a set of named variables and is organized in a tree structure, so expressions in a given scope can access variables from an ancestor scope in the tree. However, data binding adds three powerful functions to a scope that enable you to assign an event handler to fire when a variable in scope changes as easily as you assign an event handler to fire when a button is clicked.

$watch()

This function takes an expression and a callback: the callback will be called when the value of the expression changes. For example, lets say our scope has a variable name, and we want to update the firstName and lastName variables every time name changes. With $watch, this is trivial:

$scope.$watch('name', function(value) {
  var firstSpace = (value || "").indexOf(' ');
  if (firstSpace == -1) {
    $scope.firstName = value;
    $scope.lastName = "";
  } else {
    $scope.firstName = value.substr(0, firstSpace);
    $scope.lastName = value.substr(firstSpace + 1);
  }
});

Under the hood, each scope has a list of watchers, internally called $scope.$$watchers, which contain the expression and the callback function. The $watch simply adds a new watcher to the $$watchers array, which AngularJS loops over when it thinks something that can change the state of the scope.

$apply()

When called without arguments, $apply lets AngularJS know that something happened that may have changed the state of the scope, so AngularJS knows to run through its watchers. You usually don’t have to call $apply() yourself, because directives like ngClick do it for you. However, if you’re writing your own event handler, like the swipeLeft and swipeRight directives from my guide to directives, you need to plug $apply() into your event handler. Try removing the $apply() calls from the swipeLeft and swipeRight directives in this JSFiddle and watch as the UI stops responding to swipes.

Some Important Information to $digest

$digest() is the third scope function related to data binding, and it’s the most important one. With high probability, you will never actually call $digest() directly, since $apply() does that for you. However, this function is at the core of all data binding magic, and its internals warrant some careful inspection if you’re going to be an AngularJS pro.

At a high level, $digest() runs through every watcher in the scope, evaluates the expression, and checks if the value of the expression has changed. If the value has changed, AngularJS calls the change callback with the new value and the old value. Simple, right? Well, not quite, there are a few subtleties.

1) The first subtlety is with the change callback: the change callback itself can change the scope, like we did with the name example in the $watch() section. If we had a watcher on firstName, this watcher wouldn’t fire! This is why $digest() is executed in a loop: $digest() will repeatedly execute all watchers until it goes through all watchers once without any of the watched expressions changing. In AngularJS internals, a dirty flag is set on each iteration of the $digest() loop when a change callback needs to be fired. If the dirty flag is not set after an iteration, $digest() terminates.

Of course, the $digest() loop described above can run forever, which is very bad. Internally, AngularJS uses a questionably-named field TTL (presumably “times to loop”) field to determine the maximum number of times a $digest() loop will run before giving up. By default, TTL is 10, and you will usually not run into this limit unless you have an infinite loop. If you for some reason need to tweak the TTL, the AngularJS root scope has a poorly-documented digestTtl() function which you can use to change the TTL on a per-page basis. You can read more about this function here.

2) The second subtlety is another interesting corner case with the change callback: what if the change callback calls $apply() or $digest()? Internally, AngularJS uses a system of phases to make sure this doesn’t happen: an error gets thrown if you try to enter the $digest phase while you’re already in the $digest phase.

3) Remember when we said that AngularJS scopes are organized in a tree structure and a scope can access its ancestor’s variables? Well, this means that $digest() needs to happen on every child scope in every iteration! Internally, this code is a bit messy in AngularJS, but each iteration of the $digest() loop does a depth-first search and performs the watcher check on every child scope. If any child scope is dirty, the loop has to run again!

4) Since Javascript is a single-threaded event-driven language, the $digest() loop cannot be interrupted. That means that the UI is blocked while $digest() is running, which means two very bad things happen when your $digest() is slow: your UI does not get updated until $digest() is done running, and your UI will not respond to user input, e.g. typing in an input field, until $digest() is done. To avoid a bad case of client side in-$digest-ion, make sure your event handlers lightweight and fast.

5) The final and often most overlooked subtlety is the question of what we mean when we say “checks if the value of the expression has changed”. Thankfully, AngularJS is a bit smarter than just using Javascript’s === operator: if AngularJS just used ===, data binding against an array would be very frustrating. Two arrays with the same elements could be considered different! Internally, AngularJS uses its own equals function. This function considers two objects to be equal if === says they’re equal, if angular.equals returns true for all their properties, if isNaN is true for both objects, or if the objects are both regular expressions and their string representations are equal. Long story short, this does the right thing in most situations:

angular.equals({ a : 1 }, { a : 1 }); //true
angular.equals({ a : 1 }, { a : 1, b : 2 }); // false

angular.equals([1], [1]); // true
angular.equals([1], [1, 2]); // false

angular.equals(parseInt("ABC", 10), parseInt("ABC", 10)); // true

Conclusion

Hopefully now you don’t need to go buy the recently released ng-book, which promises to teach you the answer to the question “seriously, what the does $apply and $digest mean?” Data binding seems like magic, but really its just some clever-yet-simple software engineering. You can even build your own version of AngularJS data binding if you follow the steps lined out in this awesome article. Ideally, now data binding should be a lot less confusing. Good luck and code on!

FiendishChain-TF05-JP-VG

Advertisements

My Top 5 Paleo Lifestyle Hacks for New Yorkers

It’s official: paleo was the most searched for health term on Google in 2013, and, thus, paleo is no longer weird. Well, maybe its still a little weird, but at least people don’t look at me like I’m crazy when I order a bunless burger anymore. As a matter of fact, I meet a lot of people who want to try going paleo, but they’re held back by aspects of the paleo lifestyle that seem beyond the pale to the average New York office worker.

First of all, here’s a short definition of what I mean by paleo lifestyle and nutrition:

1) Nutrition: no wheat, rice, corn, quinoa. No soy. Limit sugar. Limit carbohydrate intake to at most 75-100g / day. No oils other than avocado, coconut, and olive. Limit dairy except for butter and ghee as much as possible.

2) Lifestyle: get plenty of uninterrupted sleep, go barefoot or wear minimalist footwear

In theory, all these principles are manageable. But when you work in an office in New York, there are more than a few difficulties. Even as somebody who’s been Paleo since before moving to New York, I often struggle to avoid sugary cocktails, crappy delivery food, and dollar pizza spots. In that vein, here are my answers for the 5 most common excuses I’ve heard for why people can’t go paleo in New York.

“I want to wear minimalist shoes, but as great as Vibram FiveFingers are for the gym, I look ridiculous when I wear them with slacks and a shirt.”

While they’re not going to be mistaken for Prada or Crockett & Jones in terms of high fashion, VivoBarefoot has a few pairs of shoes that are pretty business casual friendly. Black RA Leathers and Gobis are somewhat oddly shaped but can pass for an inexpensive pair of Derbies. The RA Leathers are my go-to pair of shoes for an average day at the office. The Jay also looks pretty indistinguishable from a standard loafer. And for days when its well below freezing and the ground is covered in snow, like today, the Synth Hiker does a pretty good job keeping your feet dry and not being too gaudy.

“Wait a minute, what am I supposed to order off of Seamless if I can’t order a sandwich or cheap chinese food?”

I’m not gonna lie, if you’re looking for high quality paleo-friendly food in New York, the pickings are pretty slim on Seamless. The standard approach is “order a salad”. Some places also have salads that are pretty boss. The key is to get one with a bunch of meat or fish, if not other things. From the right places, you can basically consider it an order of meat with some veggies on the side instead of “just a salad.”

Alternatives depend on your area, you’ve got some good options in midtown, but if you work around Soho or Chinatown you’re pretty much SOL. Here are a few ideas that I’ve utilized effectively:

1) Sashimi lunch specials

2) Know the 3 roll lunch specials that every sushi place has? Order that, but ask for hand rolls with no rice. Not every place will accommodate you, so you need to experiment and figure out which sushi places work. Trust me, the simple deliciousness of salmon and avocado wrapped in nori without the extra rice is well worth the effort.

3) Bareburger. The simultaneously best and most underrated burger in New York, and they serve grass-fed beef, in addition to amazing lamb, elk, and wild boar burgers. When you’re craving a truly exceptional burger, skip the Shake Shack (not that any self-respecting New Yorker would get caught in that tourist trap) and get Bareburger delivered, you’ll be much healthier and much happier for it.

4) Dig Inn is another Midtown favorite of mine. While their beef is not grass-finished, at least their beef is partially grass fed and their salmon is wild, which is more than I can say for 99% of the places I’ve seen on Seamless.

“If I can’t drink beer, mimosas, bellinis, gin and tonics, or rum and cokes, what can I actually drink at a bar?”

Short answer: prefer straight liquor or something very close, but a nice dry red wine works reasonably well too. If you’re a guy, this’ll give you an excuse to learn to appreciate good single malt scotch like a real man. But if you really want your alcohol watered down, plain soda water with lemon or lime is a decent substitute for Sprite or whatever your sparkling sugar bomb of choice is.

If you’re at a cocktail bar, a Martini, Manhattan, Rob Roy, Vesper, or other combination of liquor, vermouth, and/or bitters works pretty well as a substitute for sugar-laden cocktails. For example, PJ Clarke’s is a favorite cocktail bar among tourists and Met Opera attendees, and their Perfect Manhattan is a reasonably good low-sugar cocktail.

If you must go for boozy brunch, skip the orange juice and go for straight bubbly. Sparkling wine is not exactly the healthiest thing in the world, but the real offender in a mimosa is the orange juice. A glass of Korbel Brut only has about 10g carbohydrate, but a glass of orange juice has about 30g of pure sugar and contributes nothing to the social relaxation effects of alcohol. Cider’s also a good alternative: a 12oz bottle of Magner’s Hard Cider has no gluten, has only 10g of carbohydrate, and tastes damn good to boot.

“If I can’t drink cappucinos, lattes, macchiatos, or any of Starbucks’ other sugar bombs, how do I get my caffeine fix in the morning?”

A surprising number of people don’t like their coffee black for some reason. Well, with bulletproof coffee, there’s no excuse. Its sweet, its fatty, its extremely good for you, and it’s freakin’ delicious. You even end up saving money on every cup because even if you go with the bulletproof coffee k-cups (which I do), they’re still a solid 50 cents cheaper than a tall medium roast from Starbucks. Add to that not having to stand in line with a bunch of people who are very cross from sleep-deprivation and you have a net win.

“What do you actually do at the gym if not spend hour after hour on a treadmill?”

The short answer, courtesy of Marks Daily Apple, is “sprint and lift heavy things”. Last year I worked primarily on improving my bench press 1 rep max and my 1 set max for pullups, which I’ll write a blog post about some other time. This year, I’m working on finally achieving my childhood dream of being able to dunk. My usual trip to the gym nowadays involves a light warmup with some stretching, jogging, and pushups, and then 2-4 exercises, usually involving bench press, pullups, squats, or kettlebell swings. Once a week I throw a sprint in there, either on my apartment building’s dog walk or at the gym on a stationary bike.

Hopefully now you have a better idea of how to rock a paleo lifestyle in NYC. I think you’ll find that it’s like riding a bike: after a little bit of practice it becomes second nature.

IMG_5016

The 80/20 Guide to Writing and Using AngularJS Filters

My directives post seems to have gone over well. I’ve received emails and comments from readers expressing how much it helped them, so I figured I’d write a post about one of the simultaneously oldest, most useful, and most under appreciated AngularJS features.

What is a filter? A filter is a function that is accessible from within any AngularJS expression in your app. Filters are primarily useful for any last-second post-processing your data needs before being displayed to the user. The general high-level structure of an AngularJS application looks like this: controllers handle making the data accessible from a given scope, directives handle the visual rules for displaying and interacting with the data, and filters help directives format the data.

If this sounds a little vague, don’t worry, we’ll walk through a few examples of common use cases for filters. Filters are much simpler to grasp than directives, but they also have more pitfalls. Each example will also demonstrate a pitfall that you may run into with each design pattern, so hopefully you’ll be able to derive all the benefit from filters without any of the headache.

1) Specifying rules for converting an object to a string

AngularJS example: The date filter

Our example: A pluralize filter, which will allow us to easily encode rules for displaying counts of things, e.g. 1 hour, 2 hours, etc.

Alternative example: Convert hashtags to Github issue URLs.

When building out a UI, you will inevitably run into a place where your UI / UX / design guy decides that the way that data is stored isn’t quite conducive to how it should be displayed. Perhaps you have separate fields for first name and last name, but your designer’s copy/pasting something like this all over the place:

{{user.name.first}} {{user.name.last}}

Naturally, as developers, we want to avoid copy/paste as much as possible – what happens when a decision is made to only display the first initial of the last name? Or when a decision is made to only store the first name? Either of these decisions will become a nightmare scenario that could lead to the worst of all programming sins: editing your code using sed. Another simple alternative would be to wrap the rule for how a name should be displayed in a function, but where would the function live? I know you weren’t thinking of attaching a formatName() function to Object.prototype. A naive approach would put this function in every single controller that needs it. However, then you have to remember to put this function in every single controller. A much better solution would be to simply use a filter:

  app.filter('displayName', function() {
    return function(name) {
      return name.first + " " + name.last;
    }
  });

Now your designer can display the username as

{{user.name | displayName}}

In addition, your designer can use this functionality to chain filters together to perform simple tasks, like limiting the length of the displayed string to 40 characters, without disrupting two-way data-binding:

{{user.name | displayName | limitTo:40}}

Lets build a slightly more useful example. Displaying units for a number is very helpful, but displaying text like “today I have performed 1 bench press rep(s)” in your app seems unprofessional. Lets write a filter that will take care of our pluralization needs, appropriately called ‘pluralize’. Check it out on JSFiddle.

angular.
  module('myApp', []).
  filter('pluralize', function() {
    return function(ordinal, noun) {
      if (ordinal == 1) {
        return ordinal + ' ' + noun;
      } else {
        var plural = noun;
        if (noun.substr(noun.length - 2) == 'us') {
          plural = plural.substr(0, plural.length - 2) + 'i';
        } else if (noun.substr(noun.length - 2) == 'ch' || noun.charAt(noun.length - 1) == 'x' || noun.charAt(noun.length - 1) == 's') {
          plural += 'es';
        } else if (noun.charAt(noun.length - 1) == 'y' && ['a','e','i','o','u'].indexOf(noun.charAt(noun.length - 2)) == -1) {
          plural = plural.substr(0, plural.length - 1) + 'ies';
        } else if (noun.substr(noun.length - 2) == 'is') {
          plural = plural.substr(0, plural.length - 2) + 'es';
        } else {
          plural += 's';
        }
        return ordinal + ' ' + plural;
      }
    };
  });

Of course, English has some pretty labyrinthine grammar rules, so this filter isn’t 100% accurate, but in most cases it will get close enough. This filter will allow us to do things like

All I Need is {{1 | pluralize:’Mic’}} // All I need is 1 Mic
I’ve visited {{3 | pluralize:’city’}} // I’ve visited 3 cities

Pitfall:

AngularJS escapes HTML in {{ }}. If you want to modify your string to have any HTML, such as converting hashtags in a git commit to github URLs, you can use the ng-bind-html or the ng-bind-html-unsafe directive, or the $compile service . There is a minor complication: ng-bind-html-unsafe is available in AngularJS 1.0.x, was deprecated somewhere in 1.1.x, and removed completely in 1.2.x, so you have to use $compile in a manner like this if you’re using a more recent version and ng-bind-html doesn’t satisfy your needs.

2) Quick hacks for functions that are not accessible from AngularJS expressions

Example: encodeURIComponent

Example: conditional filter for AngularJS pre-1.1.5

One strength of AngularJS that sometimes ends up being a weakness is its extremely dogmatic opposition to all global state. As such, everybody who is new to AngularJS inevitably spends some time trying to figure out why the hell you can’t do something like:

<a ng-href="/product/{{product.id}}?from={{encodeURIComponent('/products')}}">Go To Individual Product Page</a>

This is because AngularJS expressions don’t by default have access to the window object, i.e. the global scope of the page where encodeURIComponent lives, unless you inject $window into your controller and explicitly make it accessible from the controller’s scope. However, doing this for every single controller is a really bad idea, so the slightly more correct way of making encodeURIComponent accessible from an expression is a filter:

filter('encodeUri', function() {
  return function(x) {
    return encodeURIComponent(x);
};
});

You can then access this filter using:

<a ng-href="/product/{{product.id}}?from={{'/products' | encodeUri}}">Go To Individual Product Page</a></p>

Pitfall:

AngularJS’ docs specify an ngIf directive, however, this directive is not available in versions before AngularJS 1.1.5, which are still in heavy use. Futhermore, AngularJS expressions don’t support if statements or the ternary operator, i.e. bool ? t : f. So what do we do if we want to display a certain bit of text if one condition is true and another bit of text if the condition is false? We could use ngShow, but this seems a bit hacky.

The lack of conditional logic in expressions has been the bane of every AngularJS programmers’ existence from the very beginning. There is a pretty lively debate in the development community as to whether conditional logic belongs in templates or not. In a random aside, I stumbled across an entertaining flame war on the Go language google group a few weeks ago . In response, I’m going to stand up on my soapbox and give my two cents:

Conditional logic is a necessary and fundamental part of any templating language. Your template should have the final say on how your data is displayed. If you have to write imperative code to tell a template whether or not a div should be displayed or what color a header should be, your templating engine sucks.

Rant aside, in AngularJS we can tie the ternary operator into two-way data-binding using a filter:

.filter('conditional', function() {
  return function(b, t, f) {
    return b ? t : f;
  };
});

With this filter, you can do things like this in your HTML:

<a ng-href="{{ isProduct | conditional:'/product/':'/user/'}}{{object.id}}">My Object</a>

3) Array manipulation: searching, sorting, limiting

AngularJS Example: The wonderfully-named filter filter

AngularJS Example: The orderBy filter

Our Example: Partially hardcoding the order of an array

Alternative Example: Merge two arrays

If you’re a resident of the US and have ordered something online from a site that isn’t Amazon, likely you’ve experienced some minor annoyance having to scroll to the bottom of a country dropdown to find ‘United States’ when entering your shipping information. Lets say that you want to streamline your checkout for US customers, and put your country select in alphabetical order except for ‘United States’ being first. Obviously, there are more than a few ways of doing this, but for the sake of example, lets use a filter.

First off, lets assume that we have a list of countries as an array of objects with have a ‘name’ field, and we’re displaying this list as so:

<select ng-model="shipToCountry" ng-options="country.name for country in countries">

To order the countries alphabetically, we can use the built-in orderBy filter:

<select ng-model="shipToCountry" ng-options="country.name for country in countries | orderBy:'name'">

And now, lets write a quick filter that will move the specified country to first in our array:

.filter('hardcodeFirst', function() {
  return function(arr, field, val) {
    var first = null;
    for (var i = 0; i < arr.length; ++i) {
      if (arr[i][field] == val) {
        first = i;
        break;
      }
    }

    if (!first) {
      return arr;
    }

    var firstEl = arr[first];
    arr.splice(first, 0);
    arr.unshift(firstEl);

    return arr;
  }
});

And now we can pipe the result of our orderBy into this filter to make sure ‘United States’ comes first:

<select ng-model="countryToShip" ng-options="country.name for country in countries | orderBy:'name' | hardcodeFirst:'name':'United States'"></select>

You can see this in action on this JSFiddle.

Pitfall:

You may be tempted to use the ng-init directive to initialize a variable within an ng-repeat loop where you’re repeating over a filtered array. Try to avoid this temptation, or be very careful if you choose to do it anyway. If you use ng-init, you may force AngularJS to re-render, which will cause it to do ng-init again, and force an infinite re-rendering loop. This will manifest as the well-known “10 $digest() iterations reached. Aborting!” error, as described here.

The End

In my previous post you learned how to use directives. Now you’ve learned about how to use filters and how to avoid pitfalls, you’re one step closer to AngularJS mastery. I want to leave you with one final pitfall we should all avoid when it comes to angularJS filters: not familiarizing yourself with existing filters. AngularJS has a slew of built-in filters, so read what’s already available before you go reinvent the wheel.

HanaShuriken2

Want To Ace Your Next Developer Interview? Channel Andrew Luck

I’m going to go out on a limb and say that the single most important quality that differentiates a good software developer from an excellent software developer is the ability to spend hours on a problem where he doesn’t know if or when he’ll find the correct answer. No matter how many unit tests you write or how disciplined your coding practice is, there will inevitably be bugs. Not only that, there will be those annoying, frustrating bugs that you can’t seem to duplicate and you spend hours grinding your teeth trying to figure out why the damn thing doesn’t work. As a matter of fact, when I’m conducting an interview, I often explicitly give people a question that is too difficult to solve in the allotted timeframe, just to see how well the interviewee deals with coming to the realization that they didn’t “ace” the interview.

Those of you that follow American professional football saw this quality in practice in a very different arena last week. The Indianapolis Colts’ second year quarterback, Andrew Luck, put together a dismal first half performance in his team’s opening playoff game, turning the ball over three times en route to leading his team to a 38-10 deficit. For those who aren’t familiar with NFL scoring norms, before last weekend, only twice in the history of the league had a team won after trailing by 28 points or more. There was no doubt about it: Luck screwed up, badly and repeatedly.

However, Luck has built up a reputation as a player who continues to play with poise and confidence, no matter how bad things seem. In the end, no matter how many times the opposing Kansas City Chiefs hit him or made plays to take the ball away, he continued to play effectively. In these situations, other players often either start sulking or start playing with wild desperation. Luck certainly made some adjustments, but he continued to play to his strengths and didn’t lose faith in his abilities. More importantly, he kept his head in the game rather than succumb to doubt, as evidenced by a ridiculous play where he turned an unexpected fumble into a touchdown. In the end, the Colts pulled off an incredible comeback to win and advance in the playoffs.

As software developers, there’s definitely something we can learn here. I’ve interviewed plenty of people who have caved badly under the pressure of having to admit that they don’t know the answer. I’ve had plenty of times where I didn’t debug problems as effectively as I should have because I decided that I would not be able to do it or because I was too desperate to find the answer. In order to be an effective software developer, you need to stay calm, keep focused, and remember to do things the right way, even when you’re under a great deal of pressure.

andrew-luck