I have an object that has an XML document in one of it's fields and I'm trying to use the object in an angular expression, but angular chokes on it when it parses it (using JSON.stringify) because it finds circular references (the XML doc itself is circular). One solution would be to use a "transient"-like marker on this field so angular leaves it as-is, but I don't think that's possible without a change to AngularJS.
Use case: I am porting an existing medical web application framework to AngularJS (www.i2b2.org). The framework presents the user with some trees of data that the user drags-and-drops onto a workspace. The workspace loads third-party plugins for various types of medical analysis. The plugin interface API is similar to MS OLE - a drag and drop envelope. It's important that the plugins run without change - we have a community that we are building around common medical data formats so breaking backwards compatibility breaks the community's trust. The plugins expects one of the field on the dropped object to contain an XML document so it can parse the XML values. (Yes, I know this couples the view to the XML document, but I can't change it. In this case it ALMOST makes sense since the XML documents are the center of this universe, but still, a UI layer would have been nice, unfortunately it's too late for that now.)
My treeItem directive has a template like this:
template: '<div id="{{data.divId}}" class="tree-item {{data.cssClass}}" ' +
'draggable={{data.dnd.draggable}} '+
'dnd={{data.dnd}} '+
A controller creates a model for the treeItem like so:
catNode.dnd.data = catNode.sdxDataNode;//Set the treeItem's drag and drop data.
catNode.sdxDataNode = SDX.EncapsulateData('CONCPT',cat);//this is the OLE-like API
catNode.sdxDataNode.origData = {xmlOrig : cat.xmlOrig}; //stick the original xml doc on the OLE-like node
If I take out the last line, everything is OK until the plugin inspects the dropped object and fails to find the expected XML document. If I include the last line, this error occurs when the tree nodes are displayed:
Error: [$interpolate:interr] Can't interpolate: {{data.dnd}}
TypeError: Converting circular structure to JSON
http://errors.angularjs.org/1.2.15-build.2399+sha.ca4ddfa/$interpolate/inte….dnd%7D%7D&p1=TypeError%3A%20Converting%20circular%20structure%20to%20JSON
at http://localhost:8080/webclient/vendor/angular/angular.js:78:12
at $get.fn (http://localhost:8080/webclient/vendor/angular/angular.js:8363:26)
at attrInterpolatePreLinkFn (http://localhost:8080/webclient/vendor/angular/angular.js:6640:30)
at http://localhost:8080/webclient/vendor/angular/angular.js:6717:44
at nodeLinkFn (http://localhost:8080/webclient/vendor/angular/angular.js:6289:13)
at compositeLinkFn (http://localhost:8080/webclient/vendor/angular/angular.js:5720:15)
at compositeLinkFn (http://localhost:8080/webclient/vendor/angular/angular.js:5723:13)
at publicLinkFn (http://localhost:8080/webclient/vendor/angular/angular.js:5625:30)
at boundTranscludeFn (http://localhost:8080/webclient/vendor/angular/angular.js:5739:21)
at controllersBoundTransclude (http://localhost:8080/webclient/vendor/angular/angular.js:6330:18)
I may have an ugly workaround - stash the xml somewhere else and then pull it out just before the drop, but it's very ugly, especially for this code deep inside a treeItem. Is there any other workarounds that allow me to leave the XML in the scope object?