371273
371273

Reputation: 5446

Client subscribe not receiving data from Meteor server publish

I've been banging my head against the wall for a while now, and I assume I'm missing something simple here.

I'm running this on my Meteor server:

// --- Collections ---
Projects = new Meteor.Collection('projects');
Team = new Meteor.Collection('team');

// --- Only publish user data for users on my team ---
Meteor.publish('team', function() {
    var team = Meteor.users.findOne({_id: this.userId}).profile._team;
    console.log(Meteor.users.find({'profile._team': team}, {fields: {_id: 1, profile: 1}}).fetch());
    return Meteor.users.find({'profile._team': team}, {fields: {_id: 1, profile: 1}});
});

This finds all of the users who are on the same "team" by running a query on all user documents who have the same id in the profile._team property as the currently logged in user. You'll see the console.log(...); in the publish function (on the line before the return statement), and it correctly logs the documents I expect it to in my terminal.

Now I'm running this on my client:

// --- Data ---
Meteor.subscribe('team');
Team = new Meteor.Collection('team');

Template.team.team = function() {
    console.log(Team.findOne());
    return Team.find();
};

However, the console.log(Team.findOne()) always logs undefined, Team.find() always returns an empty array. What am I doing incorrectly that is stopping my documents from reaching the client?

UPDATE: Here's the template code.

<body>
    {{> team}}
</body>

<template name="team">
    <p>TEAM TEMPLATE WORKS</p>
    {{#each team}}
        <p>TEAM EACH WORKS</p>
        <div class="teamMember">
            {{profile.firstName}} {{profile.lastName}}
        </div>
    {{/each}}
</template>

"TEAM EACH WORKS" is never rendered inside the {{#each}} tag, but "TEAM TEMPLATE WORKS" renders as expected when it is placed before the {{#each}} tag.

Upvotes: 5

Views: 4957

Answers (2)

Xyand
Xyand

Reputation: 4488

Here is the problem:

On the client you refer to collection team:

Team = new Meteor.Collection('team');

However in the server publish function you return a cursor to users:

return Meteor.users.find({'profile._team': team}, {fields: {_id: 1, profile: 1}});

No document of team is ever published. In fact you don't even use Team and Projects in the server code.

Old answer:

Try to remove console.log(teamMates.fetch()); or add teamMates.rewind()

From the docs:

The forEach, map, or fetch methods can only be called once on a cursor. To access the data in a cursor more than once, use rewind to reset the cursor.

Upvotes: 3

Tarang
Tarang

Reputation: 75985

With meteor it will take a very short amount of time to subscribe to team. While it does this Team.findOne() will return undefined and Team.find() will give an empty array.

If you wait a second or two the data displayed on the client should match up.

You did place your return Team.find() in a template helper, which is reactive. So as soon as the data arrives on the client the UI should display the updated data as long as you have something in your HTML that uses the {{#each team}} helper

Upvotes: 2

Related Questions