0

I am using Kendo and Angular together. I am using Kendo Charts to display some data got from the database. I have a simple service using Angular $resource to get the data from the storage. It looks like this:

app.factory('statsData', function ($resource) {
    var Stats= $resource('myadress/stats/:id', { id: '@id' });

    return {
        get: function (id) {
            return Stats.get({ id: id});
        }
    }
});

So, if I execute this, I will get an array of objects that will look like this:

[
    {
        "name": "Books",
        "amount": 200
    },
    {
        "name": "Newspapers",
        "amount": 320
    },
    {
        "name": "Magazines",
        "amount": 225
    },
    {
        "name": "Shoes",
        "amount": 400
    }
]

I have a variable in my Angular controller that stores the result of the get function from the service.

$scope.chartData = statsData.get(someId);

I've declared my Kendo Chart in the HTML like this:

<div kendo-chart
    k-series="[{ field: 'amount', categoryField: 'name'}]"
    k-data-source="chartData">
</div>

So, the result I should get would really look like this:

enter image description here

The problem is that when I run the app, nothing happens. Moreover, if I change the value of the $scope.chartsData variable to a statically defined array of objects like this:

$scope.chartData = [ { "name": "Books", "amount": 200 },..];

everything works correctly and the chart is visualized properly. So, my assumption is that the problem is connected with the fact that at the time of loading the chart itself the data is still not returned from the service. How do I fix this?

Yulian
  • 6,262
  • 10
  • 65
  • 92

2 Answers2

1

Okay, I found a solution here. I've just added a k-rebind directive to my Kendo chart in the HTML so that I can make sure that it is properly bound when changes are made.

So, change this:

<div kendo-chart
    k-series="[{ field: 'amount', categoryField: 'name'}]"
    k-data-source="chartData">
</div>

To this:

<div kendo-chart
    k-series="[{ field: 'amount', categoryField: 'name'}]"
    k-data-source="chartData"
    k-rebind="chartData">
</div>

The thing is that initially there is no data in the data source that I provide via my service. And when I get the response from the server, the chart is already bound, that's why I need to add the k-rebind directive. Simple as that :)

Community
  • 1
  • 1
Yulian
  • 6,262
  • 10
  • 65
  • 92
  • 1
    A note: One should be aware, that this option will destroy the original widget and will recreate it using the changed options as stated in the documentation: http://docs.telerik.com/kendo-ui/AngularJS/introduction#update-widgets-when-options-change – timtos Oct 26 '15 at 10:22
  • Do I have a better option? – Yulian Oct 26 '15 at 11:23
1

Another remmark:

Why do not you try to set the promise resolution in the controller? something like this (to avoid further problems, at least is something I do not like at first sight)

in controller:

 statsData.get(someId).then(function(dataRecieved) {
       $scope.chartData = dataRecieved; 
 }, function(data) {
   throw new Error("something went wrong");
 });

Since your factory you return a promise

app.factory('statsData', function ($resource) {
var Stats= $resource('myadress/stats/:id', { id: '@id' });

return {
    get: function (id) {
        return Stats.get({ id: id}); // here you return the promise, 
                                    //it will resorved in controller.
    }
 }
});
JoSeTe4ever
  • 473
  • 6
  • 17