cereal
1
Hi. I have a collection that looks like
{
name: 'whatever',
servers: [ <an array of server _ids> ]
}
I have a publication that looks like this:
Meteor.publish("servers", function() {
const user = User.current();
if(user) {
return Server.find({
_id: {
$in: user.servers
}
});
} else {
this.ready();
}
});
My problem is when a server _id is added to the list of server _ids, the app doesn’t update that on the client.
My subscription is just using Tracker.autorun
let servers = [];
const computation = Tracker.autorun(() => {
Meteor.subscribe('servers');
const user = User.current();
servers = Server.find({
_id: {
$in: user.servers
}
}).fetch();
});
This isn’t re-run when user.servers changes. How can I get this behaviour?
cereal
2
I resolved this.
Publications aren’t inherently reactive. They don’t watch what’s being used, and re-run if something changes. From Meteor’s perspective,
return Server.find({
_id: {
$in: user.servers
}
});
never changes. This is the same query that ran originally, and nothing has changed.
The solution is to pass in your query as a parameter.
Meteor.publish("servers", function(ids) {
if(this.userId) {
return Server.find({
_id: {
$in: ids
}
});
} else {
this.ready();
}
});
and subscribe with
let servers = [];
const computation = Tracker.autorun(() => {
const user = User.current();
Meteor.subscribe('servers', user.servers);
servers = Server.find({
_id: {
$in: user.servers
}
}).fetch();
});
1 Like
csiszi
3
You can also use publish-composite to have reactive joined queries:
const userId = this.userId // or another user's id if it's allowed
find() {
return Meteor.users.find(userId)
},
children: [
{
find(({ servers }) {
return Server.find({ _id: { $in: servers }})
}
}
]
1 Like