0

I have a sample code that goes like this:

Client Helper:

getUsername: function (userId) {
  Meteor.call("getUsername", userId, function (err, result) {
    if(!err) {
      Session.set("setUsername", result);
    else {
      console.log(err);
    }
  });
  return Session.get("setUsername");
}

Server

Meteor.methods({
   "getUsername": function (userId) {
      var x = Meteor.users.find({_id: userId}, {fields: {username:1}}).fetch()[0];
      return x.username;
   }
});

The result of this code is an infinite loop of username passing to the client. Is there a way to stop the loop and pass only the data that is needed on the client? I believe the reactivity is causing the data to loop infinitely and I am not sure how to stop it. I tried using "reactive":false on my query in the server but it does not work.

Website Is Fun
  • 290
  • 6
  • 20
  • Why do you set username into session instead of directly returning it? – Areca Apr 29 '16 at 05:26
  • @Areca - here is the situation, I want to minimize my subscription and publication. So instead of publishing and subscribing users on the post template, all want to do is pass the post user_id to the helper as parameter and then use Meteor.call to look up the user ID on the server the return the user name. In my HTML it goes like this: `{{getUsername userId}}` – Website Is Fun Apr 29 '16 at 05:37
  • Don't do async calls in helpers. Do them in events or in this case, the template's `onCreated` callbacks. By the way, what you're doing will be _slower_ than just publishing the username as part of your publications. – Michel Floyd Apr 29 '16 at 05:39
  • @MichelFloyd - nice idea, let me try test it :) – Website Is Fun Apr 29 '16 at 05:52
  • @MichelFloyd - I am not sure how to pass "userId" from `{{getUsername userId}}` to template.onCreated . . . I am using kurounin:pagination which is hard to join two collections that is why I took this approach to just get the userID of the post and do the look up on the server rather than subscribing to the user collection and do the lookup on the client. – Website Is Fun Apr 29 '16 at 06:26
  • Use [reywood:publish-composite](https://atmospherejs.com/reywood/publish-composite) to publish _just the usernames_ of the users that are related to your primary collection. Then your helper can just lookup the username from minimongo directly. – Michel Floyd Apr 29 '16 at 06:35

2 Answers2

0

If you want to access username everywhere in client templates (so thats why you put it into session), I would not set it in template helper. I would set it on startup and get username from session in template helpers (without calling server method)

If you need username just in one template, so you want to return its value from your template helper, do not put it into session, just return it in your server method callback.

Areca
  • 1,292
  • 4
  • 11
  • 21
  • Actually I am using helper just to temporarily pass the value of the meteor call since it is not possible to pass meteor call callback. – Website Is Fun Apr 29 '16 at 05:53
0

Based on your sample code, I assume, you have a set of posts and you are retrieving user name based on user id for each post. Then instead of doing it this way, you should use publish composite package to publish related users as well.

Meteor.publishComposite('getPosts', function (postIds) {
    return [{
        find: function() {
            return Posts.find({ _id: { $in: postIds }});
            // you can also do -> return Posts.find();
            // or -> return Posts.find({ /* or what ever your selector is to get the posts you need*/ });
        },
        children: [{
            find: function(post) {
                return Meteor.users.find({ 
                    id: post.userId //or the correct field in your post document to get user id 
                }, { 
                   fields: { 
                        "profile": 1
                   } 
                });
            }
        }}
    }]
});

This way your publication will take care of publishing related users along with posts. You don't need to use methods and call them each time.

Kishor
  • 2,659
  • 4
  • 16
  • 34
  • yeah I agree and it works properly if you have custom pagination which I do not have yet. For now I am using **kurounin:pagination** and they do not have publish capable of using **publishComposite** . . Do you know a pagination package that is compatible with **publishComposite**? Thank you :) – Website Is Fun Apr 29 '16 at 07:53
  • @WebsiteIsFun I have never used a package for pagination for myself but you can see my other answer to this question http://stackoverflow.com/questions/35194437/query-from-minimongo-of-large-number-of-records-stucks-and-hangs-browser/35500518#35500518 , which specifies how to do pagination your self by taking additional parameters on the publication. I think merging these two answers will solve the issue. – Kishor Apr 29 '16 at 08:02
  • 1
    amazing, let me try to play around, I'll be back. Thank you so much. – Website Is Fun Apr 29 '16 at 08:10
  • I got the pages to work but I do not know how to group the data in to let say 10 per page. In your example code I do know how to use the function "posts-count" to display the result on each page. – Website Is Fun May 03 '16 at 05:24