Suppose I have a Meteor collection called GameStatus
. I have users with different roles, but I publish the GameStatus collection for all users. I simply use the following in server/publications.coffee
Meteor.publish 'gamestatus', ->
GameStatus.find()
For two of the roles ('S' and 'B') I have no problem when I use the following Template helper (defined in files client/views/seller.coffee and client/views/buyer.coffee)
currentRound: ->
return GameStatus.findOne().currentRound
For these I never get the following error.
Uncaught TypeError: Cannot read property 'currentRound' of undefined
But for another role ('admin'), using the same template helper (defined in file client/views/admin.coffee) gives the above show Uncaught TypeError. It works if I instead write:
currentRound: ->
return GameStatus.findOne()?.currentRound
I sort of understand why this works. I think, the collection is first not available when the page is being loaded, then it becomes available. But why does this not happen for other templates shown above?
Would really appreciate if someone can help clarify this.
I believe exactly when a collection is ready won't always be consistent, so if you want to cover all your bases, always code for the case where a collection is not ready.
There's a quick-and-dirty way of dealing with collections that aren't ready, and a more sophisticated solution you can find in the todos example.
Quick and dirty solution would look like this.
currentRound: ->
gameStatusrecord = GameStatus.findOne();
if(gameStatusRecord)
gameStatusRecord.currentRound
This will work. Until the collection is ready, currentRound will return null, and your template will briefly render and probably just show a blank for current round. So not ideal user experience but not a huge deal.
For a more sophisticated solution, you can check whether a collection that you have subscribed is ready to be queried using the "ready" function. If a collection is not ready, you can render some other template, such as "loading", which guarantees that the currentRound helper won't ever be called until the collection is ready.
For instance, in the todos example, the client subscribes to the "lists" collection on line 24 of todos.js:
var listsHandle = Meteor.subscribe('lists', function () {
Then defines a helper function for the lists template on line 80 of todos.js
Template.lists.loading = function () {
return !listsHandle.ready();
};
Then in the lists template in todos.html line 20, it doesn't try to render any templates unless the listsHandle is ready.
<h3>Todo Lists</h3>
{{#if loading}}
<div id="lists">Loading...</div>
{{else}}
<div id="lists">
{{#each lists}}
<!--etc.-->
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With