Angular.js $$hashKey Object Tracking

Angular is pretty magical the first time people see it. Automatic DOM updates when you update a variable in your JS, and the same variable will update in your JS file when someone updates its value in the DOM. This same functionality works across page elements, and across controllers.

The key to all of this is the $$hashKey Angular attaches to objects and arrays used in ng-repeats.

This $$hashKey causes a lot of confusion for people who are sending full objects to an API that doesn't strip extra data. The API will return a 400 for all of your requests, but that $$hashKey just wont go away from your objects.

Angular uses the $$hashKey to keep track of which elements in the DOM belong to which item in an array that is being looped through in an ng-repeat. Without the $$hashKey Angular would have no way to apply changes the occur in the JavaScript or DOM to their counterpart, which is one of the main uses for Angular.

So, how can we avoid the $$hashKey or remove it after it shows up on our objects? Consider this array:

users = [
    {
        first_name: "Tim"
        last_name: "Costa"
        email: "tjsail33@gmail.com"
    }
]

If we rendered that into a list using ng-repeat="user in users", each object in it would receive a $$hashKey for tracking purposes from Angular. Here are two ways to avoid this $$hashKey.

The first (and better) option is to use track by to tell Angular which key in your object is unique and can be used for tracking. The code for this is ng-repeat="user in users track by user.email". We would not want to use first_name or last_name because those are not guaranteed to be unique. Each element being tracked has to have a unique tracking key, or Angular will throw a fit. Using track by also uses fewer watchers, which leads to a performance improvement when rendering long lists.

The second option is to either use angular.toJson(user) or angular.copy(user) in the code right before you need the $$hashKey removed. This option is less attractive though because it does not remove $$hashKey from all of your Angular objects, only the one you call it on. You also do not get the performance boost from track by.

Hopefully this helped you understand the purpose of $$hashKey in Angular as well as how to avoid or remove it!