I have a collection. I need to update a property on that collection. Sed update may change a second property on the collection. I don’t need to send the first property to the client so I have {fields: {prop1: 0}} set on Collection.find on the server.
I only what the change to be sent to the client if the second property changes. My issue is that the collection is republished even when only the first property is changed (the one that isn’t sent to the client).
Is there solution to this? My current workaround is to put the first property in a second collection.
Thanks for the suggestion. Unfortunately, I’ve set it to 0 on all publications and it’s the same. I’ve even created a simple standalone test and I have the same issue. Below is my collection code. As you can see, lastAccessed is Property 1 and index is Property 2. If the index is already set to 0, then nothing should change, but the component is still being re-rendered.
Upon further inspection, I see that two re-renders are being called. The first has the lastAccessed property on only the one item that was updated. The second render has removed the lastAccessed property altogether. This doesn’t look like expected behaviour.
Did I explain myself well enough? I can push the project if it helps.
Cheers
Chris
import { Mongo } from "meteor/mongo";
import { Meteor } from "meteor/meteor";
export const Items = new Mongo.Collection("items");
if (Meteor.isServer) {
Meteor.publish("items", function itemsPublication() {
return Items.find(
{},
{
fields: {
lastAccessed: 0
}
}
);
});
}
Meteor.methods({
updateLastAccessed(id) {
Items.update({ _id: id }, { $set: { lastAccessed: new Date() } });
let item = Items.findOne({ _id: id });
if (item.index !== 0) {
let items = Items.find({}, { sort: { lastAccessed: -1 } }).fetch();
items.map((e, i) => {
Items.update({ _id: e._id }, { $set: { index: i } });
});
}
},
insert(name) {
Items.insert({name: name, lastAccessed: new Date(), index: -1 });
}
});
Ahh, I think I have resolved it. The fields need to be specified on the client, not the server. This way it is no longer updating when lastAccessed changes.
What’s even nicer here is that I don’t need to return index. I can sort on index and only need to return name.
In client, you are querying from minimongo. So even if you filter in the client, it is still possible that the publication is sending the data to minimongo. I’m not sure if that is the solution to minimize network load.
Thanks to you both for your replies - with your help and that of the chrome extension, I’ve managed to get a better understanding of how the publications work and and get to the bottom of my issue. I’ll explain for those that Google their way onto this page in the future.
The issue occurs because the Meteor method call is running on both the client and the server. So whilst the server is not publishing Property 1 (lastAccessed), both the server and client are updating the lastAccessed field. That puts it into the client collection, then takes it away again once Mongo and MiniMongo sync.
One solution is to do the processing inside the method call on the server side only. But that can create unnecessary latency. Instead, I publish both fields from the server (so they both end up in minimongo), but hide the field from the client-side query. This allows the client to make the update (without waiting for confirmation from the server), and also means that the components are not re-rendered if only Prop 1 is updated.