I have multiple charts on a dashboard that shows counts, group bys etc. Backend data has over million rows. I have decided not to use subscriptions. I don't need reactive updates to the charts.
My Server methods are using rawCollection, running aggregations to get back results and I am assigning data to my chart objects via session variables that I am setting in my client callbacks.
Server method:
function purchasedItemDollarsByCategory () {
Future = Npm.require('fibers/future');
var iCat = new Future();
Purchasing.rawCollection().aggregate([
{
$project: {
"GLCodeName": 1,
"Amount" : 1
}
},
{
$group : {
_id: "$GLCodeName",
amount: { $sum : "$Amount" }
}
},
{
$sort :
{_id : 1}
}
],
function(err,docs) {
if (err) {
iCat.throw(err);
} else {
iCat.return(docs);
}
}
);
return iCat.wait();
}
In the template, I am calling
function getPurchasedItemDollarsByCategory () {
Meteor.call('purchasedItemDollarsByCategory', function (err, results) {
if (err) {
toastr.error('Something went wrong. Could not retrieve purchased Item count');
return false;
} else {
Session.set( 'purchasedItemDollarsByCategory', results);
}
})
}
Now, I am using another function to shape the data for a chart:
function getPurchasedItemCountByCategoryChartData () {
var allItemsPurchasedByCategory = Session.get('purchasedItemCountByCategory');
var allGlCodes = [];
var allItemPurchasedCountDataPoints = [];
var contractedPurchasedCountDataPoints = [];
_.forEach(allItemsPurchasedByCategory, function(d) {
allGlCodes.push(d._id);
allItemPurchasedCountDataPoints.push(d.items);
});
Session.set('allGlCodes', allGlCodes);
Session.set('allItemPurchasedCountDataPoints', allItemPurchasedCountDataPoints);
}
Now I am assigning 'allGlCodes' and 'allItemPurchasedCountDataPoints' to highcharts config object in Template onRendered event.
Server method is working fine. Client is getting the data as well. But rendering is happening before the data is coming back. So the chart renders empty. But if I click around the app and come back to this page, I see the data. I am not sure if I understand exactly what is happening but I am guessing that the data is eventually coming back and populating the session variable and since the session is sticky, I see the data after a delay.
I would like not to render till the data comes back. So I have created a ReactiveVar in Template onCreated.
this.isLoadingA = new ReactiveVar( false );
this.isLoadingB = new ReactiveVar( false );
this.isLoading = new ReactiveVar ( this.isLoadingA && this.isLoadingB );
Now the question is where should I set these to false. I have multiple server calls going on. I could have a isLoading for each call and create a allDataReady variable. But if I try to set in my success callback to the server method:
Template.instance().isLoadingA.set( true );
I get the following error:
TypeError: Cannot read property 'isLoadingA' of null
I hope I am explaining the problem and my attempts clearly. Any thoughts?