Meteor publish unique user always return nothing

I am wondering why Meteor.users.find(this.userId); always return nothing. When I echo on console this.userId, it prints it. Please help.

Code:

Meteor.publish('login.user', function () {
if (this.userId) {
    console.log( "current logged in user ---" +this.userId );
    var users = Meteor.users.find( this.userId );
    if ( users && users._id ) {
        console.log( "meteor.users.find() call  --  " +users && users._id );
        return users && users._id;
    }
}

});

This is the subscription in a template

Template.signup.onCreated(() => {
    Tracker.autorun(function () {
        let users = Meteor.subscribe('login.user');
         if (users.ready()) {
            let myuser = Meteor.users.find({ _id: Meteor.userId() });
            if (myuser && myuser._id ) {
                console.log( myuser._id );
                return myuser && myuser._id;
            }
        }
    });
});

Blockquote

client console

Cursor {collection: LocalCollection, sorter: null, matcher: Matcher, _selectorId: “7EQGhuBszukhsYQa3”, skip: 0, …}collection: LocalCollection {name: “users”, _docs: _IdMap, _observeQueue: M…r._SynchronousQueue, next_qid: 1, queries: {…}, …}fields: undefinedlimit: undefinedmatcher: Matcher {_paths: {…}, _hasGeoQuery: false, _hasWhere: false, _isSimple: true, _matchingDocument: undefined, …}reactive: trueskip: 0sorter: null_projectionFn: doc => {…}selectorId: "7EQGhuBszukhsYQa3"transform: null__proto: Object

server console log

I20180803-11:59:20.085(1)? current logged in user —7EQGhuBszukhsYQa3

There’s a couple of things.

  • Publish functions need to return a Mongo cursor. You are returning a boolean / userId (users && users._id)
  • Your users var contains a cursor. NOT the resulting list. Use users.fetch(); to get the list of users
  • Your if statement is checking userId on a cursor (users). It will always be undefined.
  • You are using a var in your case a const will be more appropriate.

Below is what you need:

Meteor.publish('login.user', function () {
  if (!this.userId) {
    return [];
  }
  return Meteor.users.find(this.userId);
}

Then on your client somewhere:

Meteor.subscribe(‘login-user’);

1 Like

@cloudspider, please what exactly is the issue? kindly help me spell it out. Thanks for the quick response.

Sorry. Pressed “Reply” too soon

@cloudspider, my deepest appreciation goes beyond words. I’ll give it a shot.

1 Like

@cloudspider Just gave it a shot. It is still not ready. Not publishing. Kindly help me look into it. I have updated the main question to reflect the subscription.

It’s because you still have the if statement. You don’t need it:
Replace the below

    var users = Meteor.users.find( this.userId );
    if ( users && users._id ) {
        console.log( "meteor.users.find() call  --  " +users && users._id );
        return users && users._id;
    }

With this:

return Meteor.users.find(this.userId);

Its important to understand what happens with pub/sub on Meteor. Publish works by returning the cursor in your publish function. You don’t need to check here if any user is. In your case, the fix is simply to use my example. That’s all you need, will not give you errors and is secure.

2 Likes

@cloudspider, thank you. On the client, it is now returning undefined. I have not changed anything on the client as I posted it.

Well, since we are working on it anyway. You could use Meteor’s default things and simplify your code:

Template.signup.onCreated(() => {
    Meteor.subscribe('login.user');
    Tracker.autorun(function () {
        const user = Meteor.user();
        if(user) {
          console.log(user);
        }
    });
});

I strongly recommend you to read the Meteor documentation and guides regarding Meteor’s Core functionality and Meteor’s Minimongo features, since these are quite common things in Meteor:

1 Like

@cloudspider, Thanks a bunch. I appreciate. Did the trick. :smile:

1 Like

find() returns a cursor to all documents matching the selector, and not the matched document. If you want just the matched document, use findOne() instead.

1 Like