Waiting for meteor collection to finish before next step
javascript, meteor
Solution
You are right, you should ensure that code depending on fetching the content of a client-side subscribed collection is executed AFTER the data is properly loaded.
You can achieve this using a new pattern introduced in Meteor 1.0.4 : https://docs.meteor.com/#/full/Blaze-TemplateInstance-subscribe
`client/views/svg/svg.js`
Template.outer.onCreated(function(){
// subscribe to the publication responsible for sending the Pushups
// documents down to the client
this.subscribe("pushupsPub");
});
`client/views/svg/svg.html`
<template name="outer">
{{#if Template.subscriptionsReady}}
{{> svgTemplate}}
{{else}}
Loading...
{{/if}}
</template>
In the Spacebars template declaration, we use an encapsulating `outer` template to handle the template level subscription pattern. We subscribe to the publication in the `onCreated` lifecycle event, and we use the special reactive helper `Template.subscriptionsReady` to only render the `svgTemplate` once the subscription is ready (data is available in the browser). At this point, we can safely query the `Pushups` collection in the `svgTemplate` `onRendered` lifecycle event because we made sure data made its way to the client :
Template.svgTemplate.onRendered(function(){
console.log(Pushups.find().fetch());
});
Alternatively, you could use the `iron:router` (https://github.com/iron-meteor/iron-router), which provides another design pattern to achieve this common Meteor related issue, moving subscription handling at the route level instead of template level.
Add the package to your project :
meteor add iron:router
`lib/router.js`
Router.route("/svg", {
name: "svg",
template: "svgTemplate",
waitOn: function(){
// waitOn makes sure that this publication is ready before rendering your template
return Meteor.subscribe("publication");
},
data: function(){
// this will be used as the current data context in your template
return Pushups.find(/*...*/);
}
});
Using this simple piece of code you'll get what you want plus a lot of added functionalities. You can have a look at the Iron Router guide which explains in great details these features.
https://github.com/iron-meteor/iron-router/blob/devel/Guide.md
EDIT 18/3/2015 : reworked the answer because it contained outdated material and still received upvotes nonetheless.
Problem
I have a Meteor template that should be displaying some data. ``` Template.svg_template.rendered = function () { dataset_collection = Pushups.find({},{fields: { date:1, data:1 }}, {sort: {date: -1}}).fetch(); a = moment(dataset_collection[0].date, "YYYY/M/D"); //more code follows that is also dependent on the collection being completely loaded }; ``` Sometimes it works, sometimes I get this error: Exception from Deps afterFlush function: TypeError: Cannot read property 'date' of undefined I'm not using Deps in any context. As I understand it, the collection is being referenced before it is completely finished loading. I therefore would like to figure out how to simply say "wait until the collection is found before moving on." Should be straightforward, but can't find an updated solution.