Search code examples
javascriptmongodbmeteorminimongo

Meteor : Changes in collections are not reflected in rendered HTML


I have been trying to doing some very simple publish/subscribe in Meteor and I cannot get it to work as I expect from reading the sources available such as the Meteor documentation.

I am using a Macbook Pro with OSX Yosemite and running Node.js v0.10.40, Meteor v1.1.0.2 and Chrome Version 43.0.2357.132 (64-bit).

Here is what I am experiencing with two different examples:

First: Simple todos tutorial.

simple-todos.html

<head>
  <title>Todo List</title>
</head>

<body>
  <div class="container">
    <header>
      <h1>Todo List</h1>
    </header>

    <ul>
      {{#each tasks}}
        {{> task}}
      {{/each}}
    </ul>
  </div>
</body>

<template name="task">
  <li>{{text}}</li>
</template>

simple-todos.js

Tasks = new Meteor.Collection("tasks");

// simple-todos.js
if (Meteor.isClient) {
  // This code only runs on the client
  Template.body.helpers({
    tasks: function(){
      Tasks.find({});
    }
  });
}

Problem description

The tutorial states that when adding items to the Tasks it should be reflected live in the browser. It does not. I have tried adding items as Tasks.insert({text: "todo from server", createdAt: new Date()}) in the JS console in Chrome and in the meteor shell. I have also added items using meteor mongo and still no changes in the rendered client view

The autopublish package is installed and I can insert and query the Tasks collection from the JS console in the browser, but the changes are not reflected in the rendered HTML.

Second: A simple publish/subscribe scenario

Basic.html

<head>
  <title>basic</title>
</head>

<body>
  <h1>Welcome to Meteor!</h1>
  <p>text gets pushed</p>
</body>

Basic.js.

MessageColl = new Mongo.Collection("messages");

if(Meteor.isServer){
  Meteor.publish("messages",function(){
    MessageColl.find({});
  })
}

if(Meteor.isClient){
  Meteor.subscribe("messages", {
    onReady: function () { console.log("onReady And the Items actually Arrive", arguments); },
onError: function () { console.log("onError", arguments); }
  });
}

Problem description

When the autopublish package is added to my project everything works as intended. I can insert new items from the JS console in Chrome and I can query the MessageColl collection and retrieve the results as well.

When the autopublish package is removed I can insert items in the MessageColl collection from the JS console in Chrome and verify that they have been added by querying the collection in the meteor shell. However when I try to query either using MessageColl.findOne() or MessageColl.find().fetch() the return value is undefined.

All changes being done in the structure of the HTML-document gets pushed as expected.

Neither the onReady or the onError callback functions gets called, so that points toward an issue related to the subscribe method.


Solution

  • I think both problems are pretty straightforward to solve (but frustrating when you can't work out why - I've been there). Basically, you aren't actually returning anything from your functions so your code doesn't have a result.

    In your template helper you need to add return like this:

    tasks: function(){
      return Tasks.find({});
    }
    

    Similarly, in your publication you also need return like this:

    Meteor.publish("messages",function(){
      return MessageColl.find({});
    })