Sean
Sean

Reputation: 1364

Chart is not populating when getting the data from AJAX call

I have this very annoying problem and I feel I have an idea why it is caused but cannot for the life of me get it fixed. Maybe it's because I don't know a fundamental rule of programming....

So let me demonstrate the issue:

HTML:

<!DOCTYPE html>
<html lang="en" ng-app="angularApp">
  <head>
    <meta charset="utf-8">
    <link href="/css/bootstrap.css" rel="stylesheet">
  </head>
  <body>
    <section>
      <div class="container">
          <div class="row">
            <div class="col-md-8">
              <div class="panel panel-default">
                <div class="panel-heading">
                  <h3 class="panel-title">Wall</h3>
                </div>
                <div class="panel-body">
                  <div ng-controller="wallPosts">
                    <div class="panel panel-default post" ng-repeat="post in posts">
                      <div class="panel-body">
                        <div class="row">
                          <div class="col-sm-3">
                            <canvas id="pie" class="chart chart-pie" chart-data="data" chart-labels="labels" chart-options="options">
                            </canvas> 
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div><!-- col-md-8 end -->
          </div>
      </div>
    </section>

    <!-- Bootstrap core JavaScript-->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="/jsLib/bootstrap.js"></script>
    <script src="/jsLib/angular.min.js"></script>
    <script src="/angular/angularApp.js"></script> 
    <script src="/jsLib/chart.js/dist/Chart.min.js"></script>
    <script src="/jsLib/angular-chart.js/dist/angular-chart.min.js"></script>
    <script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script>
    </script>
  </body>
</html>

Angular Controller:

var angularApp = angular.module('angularApp', ['chart.js']);

angularApp.controller('wallPosts', ['$scope', '$http', function($scope, $http){
    $scope.posts = [];
    $scope.labels = ["Agree", "Disagree"];
    $scope.data = [];

    $http.get('/api/posts')
        .success(function(res){
            $scope.posts = res.posts;
            //$scope.data = [100, 500];
            $scope.data = [res.posts.agreeCounter, res.posts.disagreeCounter];
        })
        .error(function(data, status){
            console.log(data);
        });
}]);

The API response looks like this:

"posts": [
        {
            "postID": "postID1233",
            "title": "testTitle",
            "description": "testDescription",
            "agreeCounter": 100,
            "disagreeCounter": 50
        }]

The problem is that the "canvas" seems to be getting generated right-away without the data I am passing through. When I pass the $scope.data as [100, 50] (statically), it works.

By the way, the res.posts works as I have tested that with post.title, post.description etc (it also has post.agreeCounter) so that is not the issue.

So how do I go about sorting this out? Any input will help.

Thanks again, Shayan

Upvotes: 0

Views: 247

Answers (1)

Yury Tarabanko
Yury Tarabanko

Reputation: 45106

It seems you need a chart for every post, right?

Change your template to get data for every post

<div class="panel panel-default post" ng-repeat="post in posts">
  <div class="panel-body">
    <div class="row">
      <div class="col-sm-3">
        <canvas class="chart chart-pie" 
            chart-data="post.data"
            chart-labels="labels"
            chart-options="options"
        ></canvas>
      </div>
    </div>
  </div>
</div>

And populate post.data for each incomming post

 $http.get('/api/posts')
   .success(function(res) {
     $scope.posts = res.posts;

     // populate post.data
     $scope.posts.forEach(function(post) {
        post.data = [post.agreeCounter, post.disagreeCounter];
     });
   })

BTW IDs must be unique within document. You shouldn't use static id (id="pie") inside ng-repeat. It will generate multiple nodes with the same id.

Upvotes: 1

Related Questions