TypeError: Cannot read property "childNodes" from undefined angular

I am stuck with this error, I have a custom directive for creating a histogram that is generated from a json file.

Here is my code, I have an Index.Html page where one view is routed inside based on navigation here

index.html

<head> <title>DiginRt</title> <body ng-app="DiginRt" class=" pace-done" cz-shortcut-listen="true"> <div id="header-topbar-option-demo" class="page-header-topbar"> <div id="page-wrapper"> <div id="title-breadcrumb-option-demo" class="page-title-breadcrumb"> <div class="page-header pull-left"> <div class="page-title"> Dashboard</div> </div> <div class="clearfix"> </div> </div> <div class="page-content" ui-view> // Here i load the view for the dashboards </div> </div> </div> </div> <script src="script/jquery-1.10.2.min.js"></script> <script src="script/jquery-ui.js"></script> <script type="text/javascript"> var $j = jQuery.noConflict(); </script> <script type="text/javascript" src="script/prototype.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.js"></script> <script type="text/javascript" src="script/d3.js"></script> <script src="script/angular-ui-router.min.js"></script> <script type="text/javascript" src="script/jquery.jsPlumb-1.4.1-all-min.js"></script> <script type="text/javascript" src="script/plumb.js"></script> <script type="text/javascript" src="script/app.js"></script> </body> </html> 

Dashboard.HTML:

 <body ng-controller="DashboardCtrl"> <div id="main_wrapper"> <div id="toolboxControl"> <div id="containerChart"> <ul> <li> <a ng-click="addWidget()" href="#controlflow">Charts</a> <div id="controlflow" class="containerChart"> <input ng-model="searchCommonValue" class="form-control" type="search" placeholder="Search controls..."> <div plumb-menu-item ng-repeat="widget in dashboard.widgets | filter : searchCommonValue" class="menu-item" data-identifier="{{widget.id}}" data-title="{{widget.name}}" draggable> <img class="toolheader" src="{{widget.Icon}}"> <div class="toolcontent">{{widget.name}}</div> </div> </div> </li> </ul> </div> </div> <div ng-controller="CustomWidgetCtrl" id="container" class="drop-container" ng-click="addEvent($event)" droppable> <div plumb-item class="item" style="margin: 20px; top: 60px; left: 200px; height: 300px; width: 500px;" ng-repeat="widget in dashboard.widgets" ng-style="{ 'left':widget.sizeX, 'top':widget.sizeY }" data-identifier="{{widget.id}}"> <div class="box"> <div class="box-header"> <h3>{{ widget.name }}</h3> <div class="box-header-btns pull-right"> <a title="settings" ng-click="openSettings(widget)"><i class="glyphicon glyphicon-cog"></i></a> <a title="Remove widget" ng-click="remove(widget)"><i class="glyphicon glyphicon-trash"></i></a> </div> </div> <div class="box-content"> <!-- <bars data="40,4,55,15,16,33,52,20"></bars> --> <bargraph id="d3bar" datajson="sample.json" xaxis-name="Year" xaxis-pos="905" yaxis-name="Frequency" yaxis-pos="12" d3-format=".0%"> </div> </div> </div> </div> </div> </div> </div> </span> </div> 

App.js:

  var routerApp = angular.module('DiginRt', ['ui.bootstrap', 'ui.router']); routerApp.config(function($stateProvider, $urlRouterProvider) { $urlRouterProvider.otherwise('/dashboard'); $stateProvider.state('dashboard', { url: '/dashboard', templateUrl: 'Charts.html', controller: 'DashboardCtrl' }) }); routerApp.controller('DashboardCtrl', ['$scope', '$timeout', function($scope, $timeout) { $scope.gridsterOptions = { margins: [20, 20], columns: 4, draggable: { handle: 'h3' } }; $scope.dashboards = { '1': { id: '1', icon: 'images/icons/chart_line.png', name: 'Home', widgets: [{ col: 0, row: 0, sizeY: 1, sizeX: 1, icon: 'images/icons/chart_line.png', name: "Stocks per store" }] } }; } ]) routerApp.controller('CustomWidgetCtrl', ['$scope', '$modal', function($scope, $modal) { $scope.remove = function(widget) { $scope.dashboard.widgets.splice($scope.dashboard.widgets.indexOf(widget), 1); }; $scope.openSettings = function(widget) { $modal.open({ scope: $scope, templateUrl: 'chart_settings.html', controller: 'chartSettingsCtrl', resolve: { widget: function() { return widget; } } }); }; } ]) var BarGraph = Class.create({ initialize: function(datajson, xaxisName, xaxisPos, yaxisName, yaxisPos, d3Format) { this.datajson = datajson; this.xaxisName = xaxisName; this.xaxisPos = xaxisPos; this.yaxisName = yaxisName; this.yaxisPos = yaxisPos; this.d3Format = d3Format; }, workOnElement: function(element) { this.element = element; }, generateGraph: function() { //d3 specific coding var margin = { top: 20, right: 20, bottom: 30, left: 40 }, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var formatPercent = d3.format(this.d3Format); var x = d3.scale.ordinal().rangeRoundBands([0, width], .1); var y = d3.scale.linear().range([height, 0]); var xAxis = d3.svg.axis().scale(x).orient("bottom"); var yAxis = d3.svg.axis().scale(y).orient("left").tickFormat(formatPercent); var svg = d3.select(this.element).append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom).append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); d3.tsv(this.datajson, function(error, data) { if (error) return console.warn(error); //console.log(this.xaxisName); x.domain(data.map(function(d) { return d.letter; })); y.domain([0, d3.max(data, function(d) { return +d.frequency; })]); svg.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(xAxis).append("text").attr("x", this.xaxisPos).attr("dx", ".71em").style("text-anchor", "end").text(this.xaxisName); svg.append("g").attr("class", "y axis").call(yAxis).append("text").attr("transform", "rotate(-90)").attr("y", this.yaxisPos).attr("dy", ".71em").style("text-anchor", "end").text(this.yaxisName); svg.selectAll(".bar").data(data).enter().append("rect").attr("class", "bar").attr("x", function(d) { return x(d.letter); }).attr("width", x.rangeBand()).attr("y", function(d) { return y(d.frequency); }).attr("height", function(d) { return height - y(d.frequency); }); }.bind(this)); } }); routerApp.directive('bargraph', function() { // Angular Directive return { restrict: 'EA', // Directive Scope is Element replace: true, // replace original markup with template transclude: false, // not to copy original HTML DOM compile: function(elem, attrs) { // the compilation of DOM is done here. // It is responsible for produce HTML DOM or it returns a combined link function // Further Docuumentation on this - http://docs.angularjs.org/guide/directive console.log(attrs.id); console.log(attrs.datajson); var html = "<div id='" + attrs.id + "' ></div>"; // the HTML to be produced var newElem = $(html); elem.replaceWith(newElem); // Replacement of the element. var ourGraph = new BarGraph(attrs.datajson, attrs.xaxisName, attrs.xaxisPos, attrs.yaxisName, attrs.yaxisPos, attrs.d3Format); ourGraph.workOnElement('#' + attrs.id); // Work on particular element ourGraph.generateGraph(); // here is the error! } } }); 
+5
source share
3 answers

There was no angular code in the html and script. A few things I did:

  • added <html ng-app="routerApp"> to the html page
  • added var routerApp = angular.module('routerApp', []); to js file

I created a PLUNK with the results. The only difference between your code is that it was easier for me to find the TSV sample file, not the JSON file that you referenced in your code. So, I changed from d3.json to d3.tsv , but that really doesn't matter here. Hope this helps.

+6
source

Your HTML has extraneous, open, and erroneous tags that seem to be struggling with Angular parsing. I would recommend checking your HTML for validity, as this will fix the problem you are having.

If you want examples, I can provide some, just let me know in the comments.

+3
source

I had these problems before, and this is due to the directive in which the replace option is set to true. Therefore, the idea may arise to check whether you really need a replacement option in your particular case.

+1
source

Source: https://habr.com/ru/post/1209513/


All Articles