txbm / angular-chartjs

Directive set for the ChartJS library. Supports data bindings and attribute-level specification for chart specific options. The only Angular ChartJS module that supports ALL chart options as HTML5 attributes :)
MIT License
146 stars 37 forks source link

asynchronous data question #25

Closed jbelis closed 9 years ago

jbelis commented 9 years ago

Hi,

I am looking for additional information about async chart data. Specifically, I provide the chart data as a promise, and it seems the module is not waiting for the data promise to be resolved. The following errors is thrown to the js console as soon a the controller returns:

TypeError: Cannot read property 'length' of undefined
    at Object.Chart.Type.extend.buildScale (http://localhost:1509/bower_components/chartjs/Chart.js:2136:25)
    at Object.Chart.Type.extend.initialize (http://localhost:1509/bower_components/chartjs/Chart.js:2065:9)
    at Object.Chart.Type (http://localhost:1509/bower_components/chartjs/Chart.js:811:19)
    at Object.Chart.Type.extend.ChartType (http://localhost:1509/bower_components/chartjs/Chart.js:1014:18)
    at Chart.Type.extend.Chart.(anonymous function) [as Bar] (http://localhost:1509/bower_components/chartjs/Chart.js:1042:12)
    at postLink (http://localhost:1509/bower_components/ng-chartjs/dist/angular-chartjs.js:88:35)
    at http://localhost:1509/bower_components/angular/angular.js:7113:44
    at nodeLinkFn (http://localhost:1509/bower_components/angular/angular.js:6711:13)
    at compositeLinkFn (http://localhost:1509/bower_components/angular/angular.js:6105:13)
    at compositeLinkFn (http://localhost:1509/bower_components/angular/angular.js:6108:13) <canvas dataset="chartdata" segment-stroke-width="5" class="ng-isolate-scope" height="150" width="300" style="width: 300px; height: 150px;"> 

Is there anything else I need to do to make this work?

Thanks

billbither commented 9 years ago

I believe I had a similar problem. When requesting data in an asynchronous callback, I get the error TypeError: Cannot read property 'datasets' of undefined

This can be reproduced in the test code app.js by putting $scope.activeData = $scope.lineChartData in a setTimeout.

AntonNiklasson commented 9 years ago

I believe this is solved by defining the datasource on the scope immediately, then "populating" it as the async callback runs.

datasource: {
  labels: [],
  datasets: []
}
txbm commented 9 years ago

I believe that is true. Regardless I'll improve that in a future release. Thanks for the info, closing for now. Please re-open if new information.

pieterdewachter commented 9 years ago

Hi,

is it possible to give morge information about this section? I am trying to fetch data from a JSON file with an $http-function in Angularjs but I received the same error as described above. In my console.log ($scope.date = data;) I receive a succes message but my data doesn't display in my html.

Can someone help me with this problem.

Big thanks.

ketsugi commented 8 years ago

I'm facing the same error.

<canvas class="chart chart-bar" chart-data="chart.data" chart-labels="chart.labels">

app.controller('dashboardController', function($scope, Sales) {
    $scope.chart = {
        labels: [],
        data: []
    }

    Sales.get().then(function(data) { // async data call via REST API
        for (i = data.length - 1; i >= 0; i--) {
            date = moment().month(data[i].month).year(data[i].year).format('MMM YYYY');

            $scope.chart.labels.push(date);
           $scope.chart.data.push(data[i].total);
        }
    });
});

As you can see I've already initialised the two arrays at the top of the controller, but am still getting the same cannot read property 'length' of undefined error

Alex-Cosma commented 8 years ago

Having the same issue. Any solutions?

Alex-Cosma commented 8 years ago

I actually got to fix the problem myself, the solution was ridiculous and made me feel retarded. The structure of the 'data' array should be something like: data = [[1, 2, 3, 4], [8, 7, 6, 5] ] Problem was that I had only one series, not more, therefore from the backend I sent a response looking like: response = [1, 2, 3, 4] Whereas the correct version would have been response = [[1, 2, 3, 4]] And well, the solution was to simply set: scope.data = [response]

I'm pretty sure I'm the only one with this problem as it's ridiculously obvious however, maybe, just maybe someone else has encountered this as well and is struggling with it so that's why I took the time to write it. All the best!

ombalakumar commented 8 years ago

Thanks Alex.. I got this error and cleared it now because of your comment

Alex-Cosma commented 8 years ago

Haha! Good to know :relaxed:

dfemo commented 8 years ago

Still facing the same issue, don't know if you can provide details about how you solved it. I want to provide a barchart and still running into same length issue, if i provide response, the data are blank.

thanks

AntonNiklasson commented 8 years ago

@dfemo: You are probably trying to access an undefined array somewhere in your code. Make sure to define the structure of your data immediately, then populate the structure when the data arrives.

You can't do something like data.item.properties.length without doing something like this first:

var data = {
  item: {
    properties: []
  }
};
daniel-nalbach commented 8 years ago

Thanks, Alex. I didn't notice the array of arrays, and hit the same error as the OP. Your post helped me fix it.