meteor-vue / vue-meteor-tracker

Use Meteor Tracker reactivity inside Vue components
90 stars 20 forks source link

$subscribe is not reactive based on other data #35

Closed vilipwong closed 6 years ago

vilipwong commented 6 years ago

Version: 2.0.0-beta.3 Vue version: 2.5.16, OS: Ubuntu, Browser: Chrome

Subscriptions inside $subscribe is not reactive ?

for example:

On page load, it takes a few seconds for subscribe data to get published and send to frontend.

       $subscribe: {
            'food': function(){
                // drink data here is not reactive
                let drink = Drinks.findOne({user_id: Meteor.userId()});
                return [ {drink_id: drink._id} ];
            }
        },
        drink: function(){
           // drink data here is reactive
            let drink = Drinks.findOne({user_id: Meteor.userId()});
            return drink;
        }

Anyone facing this issue ? Or my way is wrong ?

Please advise. Thanks !

Akryum commented 6 years ago

Try:

let drink = this.drink || {};
vilipwong commented 6 years ago

@Akryum yes i tried this as well, $subscribe still not reactive, while data props is.

So the project structure is like this:

So the drink subscription is triggered in AppContainer.

and food subscription and drink data props is in router-view. (as shown in the first post)

I also noticed that parameters passed using this.$subscribe is not parsed correctly.

For example: this.$subscribe('food', {drink_id: drink._id}, {sort: {updated_at: -1}, limit: 5});

On the server side publications, the params i get is undefined for both.

and if i do this.$subscribe('food', "drink", "projection");

On the server side publications, the params i get is "d" and "r".

Akryum commented 6 years ago

Yeah, forgot to change the documentation after this breaking change.

vilipwong commented 6 years ago

I see. the params is reflecting correctly now after i wrap them in an array.

But $subscribe is still not reactive. I have tried with Meteor.userId also, it does not rerun when data changes.

I resolved to calling this.$subscribe in mounted hook :

this.$subscribe('my-sub', () => [{drink_id: this.drinkId}, {sort: {updated_at: -1}, limit: 5}])

runarberg commented 6 years ago

I am facing a similar issue:

import CollectionA from '/imports/collections/a.js';
import CollectionB from '/imports/collections/b.js';

export default {
  params: {
    paramA: { type: String, default: '' },
  },

  meteor: {
    $subscribe: {
      'subscription-a'() {
        return [this.paramA];
      },
      'subscription-b'() {
        // This publication accepts an array of ids from CollectionA.
        // Here is the bug: We never react on changes in CollectionA.
        return [CollectionA.find().map(a => a.id)];
      },
    },

    a() {
      return CollectionA.find();
    },

    b() {
      return CollectionB.find();
    },
  },
};

I want subscription-b to resubscribe with an array of ids from CollectionA once 'subscription-a' is ready. However, subscription-b is not renewed when CollectionA changes, resulting in subscription-b never resubscribing with the new values from CollectionA.

In other words: subscription-b is not reactive based on CollectionA even though the subscription function for subscription-b depends on CollectionA

As noted above, rewriting subscription-b within a mounted hook fixes this:

export default {
  // ...
  mounted() {
    this.$subscribe('subscription-b', () => [this.a.map(a => a.id)]);
  },
};
Akryum commented 6 years ago

I can't reproduce in the latest version.