Deep cloning in Angular

On our latest project written in Angular, a co-worker of mine was faced with a problem which caught my attention. I decided to dive a bit deeper into it, as well as researching the reasons behind this behaviour and possible solutions.

The problem

On a certain part of the application the user was presented with data on a table. The table was constructed by utilizing an ng-repeat, which iterated over a list of elements consisting of a somewhat complicated nested structure. I don’t want to go deeper behind this choice, but to put it in a few words; It was simply not worth it to transform the data, specially since it was already neatly packaged and fed to us by our ORM, in this case Sequelize.

Problems arose when the user wanted to clone a row in this table. My first though was to simply encode and decode this row into Json back and forth, to later slice it into the array. This did however not work; ng-repeat did not like this newly cloned row. The error message told me the repeater couldn’t handle duplicated elements in the array, this was a major clue.

Some research showed me that in order for the ng-repeat to handle identical elements, Angular adds some key-value pairs of its own, preceded by two dollar signs. The problem was due to the fact that Json.stringify didn’t take this Angular-specific values into consideration, happily cloning these as well thus creating completely identical elements.

The solution

The solution lay within Angular itself. By utilizing angular.toJson and angular.fromJson this problem was easily avoided. Taking a look behind the hood reveals the magic, angular.toJson strips off any Angular specific values. Once the newly created element was sliced into the array it automagically received a new set of fresh $$-led values which ng-repeat happily accepted.

Some last words

Even though this approach worked for this specific case, it should be taken with a pinch of salt. Deep cloning in Javascript is a far more complicated beast as shown in this thread.

For more complicated use cases consider Angulars method for deep cloning.