Help! I cannot figure out how to disable reactivity or stop the subscription without refreshing!

432 views
Skip to first unread message

Ben Hammond

unread,
Dec 5, 2014, 1:11:21 AM12/5/14
to meteo...@googlegroups.com
My use case is simple: I want to publish and subscribe a collection when the page loads and then immediately freeze it until the user clicks a button to turn reactivity back on.

I had assumed, give the stop() function on the subscription return and the {reactivity : false } option on the find() method that this would be easy but nothing is working.

My route looks like this:


this.route('session', 
{
path: '/session/:id',
      onRun: function () {

          
        Meteor.call("log_activity", { action : "Load Session Page", session_id : this.params.id } );
        this.next();
      },
      waitOn: function() {

        
var v = [];

        var session_id = this.params.id;


        //console.log("waitOn - Session_ID: " + Session_ID);

        //Meteor.question_subscription = 

   //v.push(Meteor.question_subscription);
        v.push(Meteor.subscribe('questions-by-Session_ID', session_id));
        v.push(Meteor.subscribe('votes-by-Session_ID', session_id));

                
    return v;
           
  },
  data: function() {

              var session_id = this.params.id;
   //var user_id = (this.userId || 1234);

            //var question_subscription = Meteor.subscribe('questions-by-Session_ID', session_id);
            //Meteor.subscribe('votes-by-Session_ID', session_id);

            
            //var questions = Questions.find({session_id: session_id}, {sort: {likeCount : -1 }}).fetch();


            var votes = Votes.find({session_id: session_id});

            var templateData = {
                session_id : session_id,
               // question_subscription : sub,
               // question_subscription : question_subscription,
      // questions: questions,
              votes: votes
    };
   
    return templateData;
  }
        ,fastRender: true
});
And my template helper looks like this:

 Template.session_questions.helpers({
        'questions' : function() {

            return Questions.find({}, {sort: {likeCount : -1, reactive : false }});
         }


     });



This is, might I add, just the most recent attempt. I've tried disabling fast-render, forcing a fetch(), forcing a stop() (which reloads the page with ZERO question data) and none of it works.

My test case is to open the page in a new browser, add a question, and check to ensure it doesn't appear in the first browser. It always does. Help me understand why?



Dirk Porsche

unread,
Dec 5, 2014, 7:20:40 AM12/5/14
to meteo...@googlegroups.com
Hi,

what are you actually trying to achieve?

If you just want a subset of the 'Questions' you might want to store the 'session_id' as a field and select on it when subscribing. You can subscribe a collection multiple times. But I'm not sure what you trying to do. A more top level use-case might be helpful to give you advice.

Regards,
Dirk  

Ben Hammond

unread,
Dec 5, 2014, 11:20:30 AM12/5/14
to meteo...@googlegroups.com
I want to disable any form of update to the Questions collection.

I want to make it so that, once the code has run, no data from the server is rendered until I run code to turn it back on.

If I load the page, turn off reactivity, with 10 items in a list and another user adds an 11th item, I don't want the first user to see 11 items until I turn the subscription back on.


The use case is pretty simple: We have a large, complex set of data sorted by vote and my product owner doesn't want that data shifting around constantly unless the user has specifically turned automatic refreshing on.

Dirk Porsche

unread,
Dec 6, 2014, 3:04:20 PM12/6/14
to meteo...@googlegroups.com
Sorry for the late reply. I forgot to subscribe the thread.

In my opinion it would be generally unwise to tinker with pub/sub mechanism. You should build your app around the functionality Meteor provides.

Nevertheless, you have a valid use case. And I see some ways to achieve the desired functionality.

I would do this:

Provide a timestamp storing the questions creation date, e.g. createdAt: new Date() when creating a question.

Make the publication of the question collection accept a 'untilThen' parameter and use this date to filter the questions: Questions.find({createdAt: {$lt: untilThen}}) und publicise the returned cursor.


When subscribing to the collection use 'new Date' as the parameter.

Questions created after that date shouldn't update the client subscription.

Provide a 'update' button, that stops the current subscription and subscribes anew with the then-actual-date.

What do you think? Should that work?

Another approach might be to copy the content of the subscribed collection to a local one (created on the client without giving it a string parameter on instantiation) and than forget that subscription, or even monitor it to give the user some visual feedback that some new question has been created.

Might work as well. But looks a little bit more complicated and performance intensive.


In the first scenario you could achieve the user update notification with a second light-weight (only publishing the id and creation date of questions) ...

Best regards and good luck.
Dirk

Ben Hammond

unread,
Dec 6, 2014, 3:23:55 PM12/6/14
to meteo...@googlegroups.com
Thanks for the suggestions.

I think I'm going to use the local copy approach. That way I can maintain the subscription in the background and update the snapshot with a quick find.

--
You received this message because you are subscribed to a topic in the Google Groups "meteor-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/meteor-talk/VGk_RabEw70/unsubscribe.
To unsubscribe from this group and all its topics, send an email to meteor-talk...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/meteor-talk/a5204891-7025-4c85-b49e-973326d325f8%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Jan Hendrik Mangold

unread,
Dec 6, 2014, 3:31:34 PM12/6/14
to meteo...@googlegroups.com

On Dec 5, 2014, at 08:20, Ben Hammond <ben.a....@gmail.com> wrote:

I want to make it so that, once the code has run, no data from the server is rendered until I run code to turn it back on.

what about saving the handler for your subscription and calling the stop method on it?

mySubscription = Meteor.subscribe(‘largeAndComplexSetOfData’);
….
mySubscription.stop(); // at this point changes on the server will no longer be reactively pushed to client

Ben Hammond

unread,
Dec 6, 2014, 3:34:25 PM12/6/14
to meteo...@googlegroups.com
With the code above, calling stop() re-renders the entire route without any subscription data.

I have no idea why, I was expecting stop to do what I needed to do. That's why I was dismayed when it didn't work.

--
You received this message because you are subscribed to a topic in the Google Groups "meteor-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/meteor-talk/VGk_RabEw70/unsubscribe.
To unsubscribe from this group and all its topics, send an email to meteor-talk...@googlegroups.com.

Dirk Porsche

unread,
Dec 6, 2014, 3:43:32 PM12/6/14
to meteo...@googlegroups.com
@Ben Hammond that is the documented behaviour. Calling stop() removes all data from the client:

Meteor.subscribe returns a subscription handle, which is an object with the following methods:

stop()

Cancel the subscription. This will typically result in the server directing the client to remove the subscription's data from the client's cache.



For more options, visit https://groups.google.com/d/optout.



--
Gruß
Dirk

mk_too

unread,
Dec 6, 2014, 3:49:52 PM12/6/14
to meteo...@googlegroups.com
stop()

Cancel the subscription. This will typically result in the server directing the client to remove the subscription's data from the client's cache.

Publish / subscribe is used to control what data the client has from the server.  Template helper functions control which data is displayed on your web page.  

I think you were on the right track setting {reactive: false} in your helper.  You could then use Session variables to trigger when that helper reruns and the helper ( and template ) would not refresh when new data is received from the server.

Ben Hammond

unread,
Dec 6, 2014, 3:50:34 PM12/6/14
to meteo...@googlegroups.com
Interesting. I missed that line, then, when I was parsing the docs.

I have no idea why its implemented that way. What's the point of removing the data from the client? I don't understand the use case for stop, then.

I'd prefer if removing the data was an optional parameter, or a different method entirely (.cancel() perhaps?)

Dirk Porsche

unread,
Dec 6, 2014, 3:53:26 PM12/6/14
to meteo...@googlegroups.com
Well it's useful. For example when the parameters of a subscription change, you would stop() the current subscription and resubscribe with the changed parameters, when paging for example.


For more options, visit https://groups.google.com/d/optout.



--
Gruß
Dirk

Ben Hammond

unread,
Dec 6, 2014, 3:55:15 PM12/6/14
to meteo...@googlegroups.com
Oh, interesting. I had assumed paging was mostly implemented through cursor finds rather than changing subscriptions. I guess I could see how that might not scale as effectively for very large datasets through, since you'd be forced to wait for the entire set rather than just the page.

Ben Hammond

unread,
Dec 6, 2014, 3:56:12 PM12/6/14
to meteo...@googlegroups.com
Looks like reactive : false is now working. I'm not sure why it works now when I didn't earlier. Apparently something in my route has changed? I'll need to dig around to figure out what and why.

Still, success is success, thanks everyone!

Kelly Copley

unread,
Dec 6, 2014, 4:00:23 PM12/6/14
to meteo...@googlegroups.com
For your use case I would think that setting the reactive:false option would be sufficient.. It will stop the jumping around that you described. If you are looking to implement something like you have 5 more posts or something of that nature I would set the reactivity on the cursor to false and do something like limit by a date less than the current Date() and store the date in a reactive source such as Session and then just change that to cause an invalidation.

If by some chance that option won't work, I'd recommend using something such as https://atmospherejs.com/richsilv/dumb-collections

Hope this helps

You received this message because you are subscribed to the Google Groups "meteor-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-talk...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/meteor-talk/CALORFO0juiYeypnzR3X%2B2_GdDbPeHN75qGtdvFqjpnVWETM9bQ%40mail.gmail.com.

Kelly Copley

unread,
Dec 6, 2014, 4:00:46 PM12/6/14
to meteo...@googlegroups.com
glad to see you got it working.

--
You received this message because you are subscribed to the Google Groups "meteor-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-talk...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/meteor-talk/CAOi1uCE_tpH6ic67OkZaR6QZYHVoN_B22Vrmn8jB1-Z-J2drzw%40mail.gmail.com.

Jan Hendrik Mangold

unread,
Dec 6, 2014, 4:03:20 PM12/6/14
to meteo...@googlegroups.com

On Dec 6, 2014, at 12:43, Dirk Porsche <dirkpo...@googlemail.com> wrote:

@Ben Hammond that is the documented behaviour. Calling stop() removes all data from the client:

Doah, should have tested that.

Ben Hammond

unread,
Dec 6, 2014, 4:04:59 PM12/6/14
to meteo...@googlegroups.com
Woah, Kelly, that is a really cool module. Thank you for sharing it!

I'm sure at some point I'll be asked to make that kind of computation, it'll be nice to have this in my back pocket.

Cheers!

--
You received this message because you are subscribed to a topic in the Google Groups "meteor-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/meteor-talk/VGk_RabEw70/unsubscribe.
To unsubscribe from this group and all its topics, send an email to meteor-talk...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages