Meteorite pattern reloads infinity

I have a problem working with Meteor.

I have a page with a question that I want to increase the counter view whenever it is displayed.

So in my template function I write

Template.questionview.helpers({ question : function() { if(Session.equals('main_template_name', 'question')) { console.log(Session.get('question_id')); Questions.update({ _id: Session.get('question_id') }, { $inc: { views: 1 } }); } }); 

Now the problem is, when I visualize the presentation of the question and update the question, the view is updated again because it is a reflective page. And then he comes into an endless loop.

Anyone have any suggestions?

+6
source share
4 answers

As a rule, in such situations, something breaks in the model. In this case, I think this is the idea of ​​a "counting glance." There are many ways to do it right. Incrementing it on rendering is wrong, since you are working with the model in the user interface code (conceptually violated in the implementation).

First save the questions that the user visited somewhere. Why does the {questionsVisited:[]} property not exist for the user?

Use the call to the Meteor.call(...) method to register the view:

 Meteor.methods({ viewQuestion: function(questionId) { // check if the user hasn't visited this question already var user = Meteor.users.findOne({_id:this.userId,questionsVisited:{$ne:questionId}}); if (!user) return false; // otherwise, increment the question view count and add the question to the user visited page Meteor.users.update({_id:this.userId},{$addToSet:{questionsVisited:questionId}}); Questions.update({_id:questionId},{$inc:{views:1}}); return true; }); 

So, what about increasing the size of the view in user interfaces? Well, we will not do this. Allow to increase the number of views only when the question changes.

 Meteor.autorun(function () { var questionId = Session.get("question_id"); Meteor.call('viewQuestion',questionId,function(e,r) { if (r) console.log("Question " + questionId + " logged an increment."); else console.log("Question " + questionId + " has already been visited by user " + Meteor.userId(); }); }); 

And get rid of all this supporting question material ...

This is even better than you wanted. Now views are not counted twice for the same user. If this is the desired behavior, remove the questionsVisited logic.

Only change the 'question_id' session variable when you actually change the logical question the user is working with.

+4
source

I solved this problem using meteor collection hooks

Install it first

 >_ meteor add matb33:collection-hooks 

Then in your model

 Questions.after.findOne(function (userId, selector, options, doc){ Questions.update({_id: doc._id},{$inc:{views:1}}); }); 

And KABOOM is he

+1
source

Instead of putting in an assistant, I would put this logic in a visualized event, i.e.

 Template.questionview.rendered ... 

See the Meteor docs .

0
source

If you use publication and subscription (you don't care), you can do this in your publishing method, for example

 Meteor.publish('posts', function(id) { Posts.update({_id:id},{$inc:{view:1}}); return Posts.find({_id: id}); }); 

or when calling a subscription callback

  Meteor.subscribe("posts" , id { onReady: function() { Meteor.call("incrementView", id);}}); 

this way you only increase the counter every time users open the browser.

0
source

All Articles