AngularJS passing to directive heavy JSON file
-
21-12-2019 - |
Question
Well, i think i located the problem of chart not showing up, and the problem is probably that i'm loading heavy JSON object from RESTful server and passing it to directive where i'm generating chart but json is not still not downloaded completly.
JSON file is almost 1mb, which i'm getting in this way:
In Controller:
dataArchive.get().then(function(result){
$scope.getData = result;
});
And HTML:
<divng-controller="archiveCtrl">
<data-graph get-archive-data="getData"></data-graph>
</div>
And in directive:
var chart = function(data){
var createchart = new AmCharts.makeChart("chartdiv", {
//
});
}
var linker = function(scope, element, attrs){
scope.$watch('data', function(){
chart(scope.data);
});
}
directives.directive('dataGraph', function(){
return {
restrict: 'E',
replace: false,
scope: {
data: '=getArchiveData'
},
template: '<div id="chartdiv"></div>',
link: linker
};
});
Probably because of this, directive template will be created empty, and chart will not be generated. How can i workaround this problem?
Solution
You are correctly using $watch
which should re-trigger the charting function, but I suggest you try a few other approaches to see which helps.
Firstly, the watch function will trigger on initial directive linking even if data
is not there yet -- it will just return undefined
, so the first time it will call the chart function with undefined
, therefore, I imagine, rendering an empty chart. Then, when the data is downloaded, it will trigger $watch
again, but perhaps your charting function will not work if called multiple times..? How about the following check:
scope.$watch('data', function(){
if (!scope.data) return
chart(scope.data);
});
Another approach which works for me when I need to wait for the resolution of some variable is using $observe
, and not adding the variable into the scope of the directive:
<data-graph get-archive-data="{{ getData }}"></data-graph>
var linker = function(scope, element, attrs){
attrs.$observe('getArchiveData', function(data){
if (!data) return;
chart(data);
});
}
directives.directive('dataGraph', function(){
return {
restrict: 'E',
replace: false,
// Remove below
//scope: {
// data: '=getArchiveData'
//},
template: '<div id="chartdiv"></div>',
link: linker
};
});