D3 Integration with Angular: "Error: Invalid value for <rect> attribute x"
angularjs, d3.js, svg
Solution
Looks like this was related to this issue: https://github.com/angular/angular.js/pull/2061
It was solved in that issue as well.
SVG elements use an XML-based schema, and are namespaced, and as such have validation rules. Certain attributes can't take an Angular interpolated directive because they expect a numeric value, and the browser validates this before Angular ever has a chance to catch it (even if the element is created and not appended to the DOM yet).
If anyone runs into this issue, hopefully this answer will help.
Problem
I'm attempting to bind SVG attributes using AngularJS. I have the following code for a resize handle of a shape: ``` // S handle. var s_handle = d3.select(document.createElementNS("http://www.w3.org/2000/svg", "rect")) .attr("id", "s-resize") .attr("x", "{{(objects['" + id + "'].w - (scope.dragHandle.width / 2))}}") .attr("y", "{{(objects['" + id + "'].h - (scope.dragHandle.width / 2))}}") .attr(scope.dragHandle) .attr("cursor", "s-resize") .call(sresize); $compile(s_handle.node())(scope); element.append(s_handle); ``` When I run this code, I get the following error: ``` Error: Invalid value for <rect> attribute x="{{(objects['9b320170-6365-4f40-801d-a7a5c6b936f9'].w - (scope.dragHandle.width / 2))}}" d3.min.js:1 Error: Invalid value for <rect> attribute y="{{(objects['9b320170-6365-4f40-801d-a7a5c6b936f9'].h - (scope.dragHandle.width / 2))}}" d3.min.js:1 ``` I tried removing the append step to isolate the issue - and it looks like the issue actually happens when I set the `x` and `y` attributes, even before the Angular compile stage. Note that I have this method working with another SVG object using the `transform` attribute, which natively accepts a string. Has anyone run into this problem before? Are there any solutions? Thank you. Edit: Been stepping through and it looks like $compile` isn't actually changing the element at all. Could this be because the element is invalid?