tarmes
tarmes

Reputation: 15442

Template flick when modifying subscription

I have a Meteor template that renders the documents of a collection. The subscription is set up in the template's autorun:

Template.userSearch.rendered = ->

   Session.set "userSearchLimit", 5

   @autorun ->
      Meteor.subscribe "userSearch", "something to find", Session.get "userSearchLimit"

When the user pressed a "Load more" button I increment the userSearchLimit session variable, which causes the autorun to rerun. The subscription changes since I ask for more data, so the old subscription will be torn down and a new one created, however the first part of the actual data will be the same.

The problem is that the entire list is being redrawn, causing a horrible flicker. When I put debug logging into the find() method as suggested here, then I see that the documents are first being removed, then added back again.

I would have expected the server to avoid resending data that already exists on the client.

How can I solve this?

To further confuse the issue I also tried using ddp-analyzer to see what data was being sent. As soon as I use that then only the new data gets sent and the flicker is eliminated. As soon as I stop using it the problem comes back.

Upvotes: 1

Views: 93

Answers (1)

tarmes
tarmes

Reputation: 15442

I've solved this by manually waiting for the new subscription to be ready before taking down the previous one:

currentMatchingSub = null
prevMatchingSub = null

subscribeToUserSearch = (limit) ->

   prevMatchingSub = currentMatchingSub
   currentMatchingSub = Meteor.subscribe "userSearch", "john baker", limit, ->

      # Only once the new subscription is ready should be take down the previous one. This ensure's
      # that there's no flicker...

      prevMatchingSub.stop() if prevMatchingSub?
      prevMatchingSub = null

Template.userSearch.rendered = ->

   limit = 5
   Session.set "userSearchLimit", limit
   subscribeToUserSearch limit

Template.userSearch.destroyed = ->

   prevMatchingSub.stop() if prevMatchingSub?
   currentMatchingSub.stop() if currentMatchingSub?

Upvotes: 1

Related Questions