Reputation: 63687
How can a query on the collection be executed first, then execute another function when a particular div
has been rendered?
If I were to do the following, I get an error from .highcharts()
stating that it is unable to find the div #chart
.
main.html
<template name="chart">
<div id="chart">{{init}}</div>
</template>
main.js
Template.chart.init = function() {
// Get results of query first
var data = myCollection.find();
data.forEach(function(row) {
console.log(data.price); // yes we received the collection
});
// Then pass to function
$('#chart').highcharts(data);
};
Now If I were to call the function highcharts()
after the template dom has been rendered via Template.chart.rendered
as shown below, I get an error stating that the variable data
is not found.
Template.chart.init = function() {
var data = myCollection.find();
data.forEach(function(row) {
console.log(data.price);
});
};
Template.chart.rendered = function() {
$('#chart').highcharts(data)
}
Here it appears that Template.chart.rendered
runs before Template.chart.init
. How can I run the highcharts
function after data
has been retrieved from mongo?
Upvotes: 3
Views: 2005
Reputation: 2978
Your first example doesn't work because Meteor calls your helper functions as it figures out what to render. At that point your chart template doesn't yet exist in the DOM.
Your second example doesn't work because of a scope problem. You're trying to use a variable in the rendered handler that only exists in init.
This should work:
Template.chart.rendered = function() {
$('#chart').highcharts(myCollection.find());
};
If you need to do calculated values, there are a couple of ways to approach it.
Approach #1: Change the collection on the client
Pros: easy and fast to develop
Cons: client browser has to do the calculation, which - depending on the collection size and the calculation - could be slow
Example:
var dataWithCalculations = _.map(myCollection.find(), function(document) {
document.someValue = document.someOtherValue * 2;
return document;
});
$('#chart').highcharts(dataWithCalculations);
I'm not sure if this approach is reactive or not. If it's not, it should be easy to fix by using a dependency.
Approach #2: Use a transform
Pros: easy and fast to develop
Cons: not reactive
Example:
Forms = new Meteor.Collection("forms", {
transform: function(document) {
document.someValue = document.someOtherValue * 2;
return document;
}
});
Approach #3: Use a custom publication
Pros: Reactive, calculation run on the server
Cons: Not easy or straightforward
Example: Check the count-by-rooms example in the Meteor documentation
Upvotes: 3