meteor subscription manager change collection name - meteor

I'm using subscriptions manager with iron-router and my problem is this one.
I have a collection "participants" with 2 publications: allParticipants and todayParticipants.
if I go to this page:
Router.map(function () {
this.route('winners', {
waitOn: function () {
return [subs.subscribe('allWinners'),
subs.subscribe('allParticipants')];
console.log("subscribed!");
},
data: function () {
return {
winners: Winners.find(),
participants: Participants.find(),
loginBox: "True"
}
}
});
AllParticipants publication is subscribed and put in cache by the subscription manager package.
If after this, I go to this page:
Router.map(function () {
this.route('participants', {
path: '/',
waitOn: function () {
return subs.subscribe('todayParticipants');
},
data: function () {
return {
participants: Participants.find()
}
}
});
I'm expecting to subscribe only the todayParticipants but as my subscription is automatically named "Participants", It uses the cached subscription from the previous page being allParticipants.
Is there a way to change the name of my subscriptions in order to have each of them in the right cache?
Thanks.

What I do in my waitOn function is first stop my subscriptions like
if (App.subs) {
for (name in App.subs) {
App.subs[name].stop();
}
}
And then I create new subscriptions
App.subs = {
settings: Meteor.subscribe('settings', project),
...
};
return [App.sub.settings, .....];
Hope this helps!

Today, there seems to be no solution to this problem.
More explanation here: https://github.com/meteorhacks/subs-manager/issues/11
What I'm doing now is using a very limited number of subscriptions (filtered mainly on user) and then I create as much data objects as I want filtering my subscriptions in different ways.

Related

Meteor subscription doesn't refresh despite WaitOn

I'm using Iron Router. I have a RouterController that looks something like this:
var loggedInUserController = RouteController.extend({
layoutTemplate: "GenericLayout",
waitOn: function () {
return Meteor.subscribe("TheDataINeed");
}
});
And I have a route defined which uses this controller to wait for the 'TheDataINeed':
Router.route("/myapp", {
name: "Landing",
controller: loggedInUserController,
data: function () {
if(this.ready()){
return {content: "page-landing"};
}
}
});
Now, the problem is the data I am subscribed to is conditional: meaning, depending on the user's role, I publish different data, like so:
if (!Roles.userIsInRole(this.userId, 'subscribed') ) {
return [
myData.getElements({}, { fields: { _id: 1, title: 1}, limit: 5 })
];
} else {
return [
myData.getElements({}, { fields: { _id: 1, title: 1} })
];
}
When the user's role is not 'subscribed', I limit the published data to 5 elements.
The problem is publishing is not reactive, so when the user changes his role for the first time to 'subscribed' and I navigate to my route ("/myapp"), the user still sees the limited number of elements instead of all of them.
Is there a way to manually re-trigger the subscription when I am loading this route? If possible, I'd like to do this without adding new packages to my app.
Not sure about that approach but can you try to set session value in route instead of subscription code. Then in a file on client side where your subscriptions are you can wrap Meteor.subscribe("TheDataINeed") in Tracker.autorun and have a session as a subscription parameter. Every time that session value is changed autorun will rerun subscription and it will return you data based on a new value.

Data from db undefined at first, then changes to actual data

I am doing a find on a collection of nodes and am then storing the info in a variable.
I am then console.logging this data to see the contents of it. The thing is, my data stays an empty array for a split second and then a new console.log is done with an array of data. See my code below:
Template.temperature.helpers({
node() {
let node = Nodes.find({_id:Session.get('selectedNode')});
console.log(node);
return '';
}
});
My console output:
1: []
2: [Object]
What could be the reason for this?
In your router, subscribe within waitOn:
Router.route('/home', {
waitOn: function() {
return [
Meteor.subscribe('nodes'),
];
},
action: function() {
if (this.ready()) {
this.render();
}
},
});
This will ensure that the route will wait until the subscription is completed before executing the route. It uses the meteor loading hook, so the wait will utilize whatever loading screen or animation you ahve setup.

Meteor: Publishing all user not working without autopublish package

I would to show a list of all users, in my template.
I have:
//publications.js
Meteor.publish('users', function() {
return Meteor.users.find({}, { fields: {username: 1, profile: 1} });
});
//router.js
Router.route('/users/add/:_id?', {name: 'users.add', controller: 'UserAddController'});
UserAddController = RouteController.extend({
subscriptions: function(){
return [ Meteor.subscribe('hospitals'),
Meteor.subscribe('roles'),
Meteor.subscribe('users') ];
},
action: function() {
this.render('addUser', {
data: function(){
return { hospital_id : this.params._id }
}
});
}
});
//client
Template.listUsers.helpers({
users: function() {
return Meteor.users.find({});
}
});
But the list keep showing only the current logged-in user. I have created a list of users using Account.createUser() function What am I doing wrong?
Thanks.
You have to subscribe to a publication using this.subscribe() in subscriptions hook:
// a place to put your subscriptions
subscriptions: function() {
this.subscribe('items');
// add the subscription to the waitlist
this.subscribe('item', this.params._id).wait();
}
Or use waitOn:
// Subscriptions or other things we want to "wait" on. This also
// automatically uses the loading hook. That's the only difference between
// this option and the subscriptions option above.
waitOn: function () {
return Meteor.subscribe('post', this.params._id);
}
By default, Meteor publishes the current user. I see that you have a addUser template and a listUsers template. The problem is that while addUser is subscribed to the users publication, listUsers is not (this would depend on what else you have in your router of course). To fix this, change the call to this.render to render the listUsers template. Then, your users helper should work, and you can render the information however you like.
I tested this with my own app (the Microscope project from DiscoverMeteor) and it worked for me. Hope it works for you too. Comment here if not, and be sure to accept this answer if it worked. =)

Meteor.publish -> All data still available

In my server folder I have a file where i'm doing the following
Meteor.publish("all_jobs", function(jobs) {
return Jobs.find();
});
Meteor.publish("user_jobs", function(user_id) {
return Jobs.find({userid: user_id}, {sort: {date: -1}});
});
On the user his blogpost page I do the following:
Session.set("userid", Meteor.userId());
Meteor.subscribe("user_jobs", Session.get("userid"));
Template.userJobs.helpers({
jobs: function(){
return Jobs.find();
}
});
On my homepage I would need all the blogpost. So i'm trying to access Meteor.subscribe("all_jobs");
The problem i'm having right now is that all the posts are showing up on my user profile instead of only the posts published by the user.
Any suggestions?
Thanks
When you make multiple subscriptions for the same collection, the results will be merged on the client. After subscribing to all_jobs, the client will now have all of the jobs in its local database until the subscription is stopped. When you go to find some of the jobs in the userJobs template, you will need to indicate which ones you actually are interested in. Modify your helper as follows:
Template.userJobs.helpers({
jobs: function() {
return Jobs.find(userid: Meteor.userId());
}
});
Found the problem. The problem was I was subscribed to all the publications because I just subscribed somewhere random in my code.
I fixed this by adding a waitOn in my route:
waitOn: function() {
return [
Meteor.subscribe("userJobs"),
];
},

Meteor Iron Router Run function when collection changes

Im new to Meteor and Im trying to figure out how to run a function after a collection change.
I have a route(iron router) that subscribes to a collection with waitOn. Which just waits for the subscrition to be ready before rendering which is what I want.
waitOn: function () {
return Meteor.subscribe('collection', this.params._id);
},
Any changes to the collection will be updated on all the clients and rendered automatically.
How would I run a function once the collection has changed?
You can use the onData hook, provided that you're returning that data using the data helper. E.g this is what a route may look like
this.route('routename',
path : '/abc',
waitOn: function () {
return Meteor.subscribe('collection', this.params._id);
},
data: function() {
return Collection.findOne({_id: this.params.id});
}
onData: function() {
//Do something when the data found by the above changes
}
});

Resources