JMA
JMA

Reputation: 994

Collection on client not changing on Meteor.subscribe with React

I am using Meteor with React JS. I get the collection of "list" by this code,

Meteor.subscribe('getList', {status:'active'},function(){
    self.setState({lists:Lists.find().fetch()});
});

Here is the code for publish,

Meteor.publish('getList', function(data){
    data.user = this.userId;
    return Lists.find(data);
});

So it is working. The problem is that I have two components that calling Meteor.subscribe('getList'). But the status is not the same.

So in other component, I have this code,

Meteor.subscribe('getList', {status:'archived'},function(){
    self.setState({lists:Lists.find().fetch()});
});

So what happens here is, if the user go to FirstComponent, this.state.lists is empty (which is correct). Then when the user navigate to SecondComponent, this.state.lists is populated with data (which is correct). But when the user go back to FirstComponent, this.state.lists still populated with data (which is wrong).

It is like that the first collection (is empty) in client is still there. Then the second collection (not empty) is added. I want to clear the collection in client before subscribing again.

By the way I am using flow-router.

Upvotes: 0

Views: 133

Answers (2)

Michel Floyd
Michel Floyd

Reputation: 20227

Since subscriptions are cumulative you should repeat the query condition in your setState functions:

let query = {status:'active'};
Meteor.subscribe('getList',query,function(){
    self.setState({lists:Lists.find(query).fetch()});
});

query = {status:'archived'};
Meteor.subscribe('getList',query,function(){
    self.setState({lists:Lists.find(query).fetch()});
});

Please note however that from a security perspective you really don't want to pass a query object from the (untrusted) client as a parameter to the subscription! From the console someone can just do:

Meteor.subscribe('getList',{});

Upvotes: 1

Travis White
Travis White

Reputation: 1977

It looks like you are setting the React state in the Meteor.subscribe onReady callback. Does each component have it's own state?

Where are you calling Meteor.subscribe from? Remember that Meteor puts subscription data in local mini-mongo and you are reading from there when you call Lists.find().

The way you have this set up, the data will not be reactive. You need to store handle to the Meteor.subscribe cursor and manage the subscription lifecycle with that.

If you could share more code, I could give a more concise answer.

Upvotes: 1

Related Questions