How to publish data without MongoDB through subscriptions in Meteor?

157 views Asked by At

Essentially, this is what I had in mind :

Client

const Messages = new Mongo.Collection("messages");

Meteor.call("message", { room: "foo", message: "Hello world");
Meteor.subsribe("messages", "foo");

// elsewhere
const messages = Messages.find({ room: "foo" });

Server

Meteor.methods({
  message: ({ room, message }) => {
    // 1. remove old messages in the room
    // 2. add new message to the room
  }
});

Meteor.publish("messages", function (room) {
   // 1. return message collection for room
});

The client, I assume, uses minimongo, which is fine, but the server does not have access to a MongoDB instance whatsoever.

What would be the implementation on the server?

1

There are 1 answers

0
Christian Fritz On

As mentioned in comments, I think this can be achieved using the manual publication methods described in the documentation. Something like this might work:

// Server:

const rooms = {};

Meteor.publish('manualMessages', function(roomId) {
  check(roomId, String);
  rooms[roomId] = this;
  this.ready();
});

Meteor.methods({
  message: ({ roomId, message }) => {
    // 1. remove old messages in the room
    const room = rooms[roomId];
    if (!room) {
      throw new Meteor.Error('no room', 'that room does not exist');
    }
    room.removed('messages', roomId);
    // 2. add new message to the room
    room.added('messages', roomId, { message });
  }
});



// Client:
const Messages = new Mongo.Collection("messages");

Meteor.call("message", { room: "foo", message: "Hello world");
Meteor.subsribe("manualMessages", "foo");

// elsewhere
const messages = Messages.find({ room: "foo" });

One thing to verify is whether this in the publish function changes per client, in which case rooms should contain arrays, or whether it is the same object for all clients, as assumed here. But hopefully this point you in the right direction.