Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reactive subscription depending on current time in Meteor

In an application that allows realtime chat between clients, I aim to integrate functionality that allows to define messages that are delivered at future points in time.

In the following example, I am able to insert messages, which are inserted directly into the template. However, I would like to display only messages that have a time smaller or equal to the current time, but automatically display messages that have future time points as soon as the time is reached. For example, if I insert a message from the console, which should be displayed 30 seconds in the future by calling Meteor.call("createMessage", 30000, "hello in 30 seconds"), the message should be automatically displayed after 30 seconds.

I started restricting the query in the publish function to time: {'$lt': new Date()}. However, I have trouble in making this reactive. I unsuccessfully tried several combinations of Tracker.autorun and cursor.observe.

Can anybody give me a hint how I accomplish the desired reactivity within the following running example?

1) html file

<body>
    {{> chat}}
</body>

<template name="chat">
 {{#each chatMessages}}
    {{time}} - {{message}} <br>
 {{/each}}
</template>

2) js file

//server and client 
Messages = new Mongo.Collection("messages"); //{time: Sun Nov 02 2014 22:17:32 GMT+0100 (CET), message: "hello"}

//server
if(Meteor.isServer){
  Meteor.methods({
    'createMessage': function(timeOffset, message){
      Messages.insert({
        time: new Date(new Date().getTime() + timeOffset),
        message: message
      });
    }
  });

  Meteor.publish("messages", function(){
    return Messages.find({
      //time: {'$lt': new Date()}
    });
  });
}

//client
if (Meteor.isClient) {
  Template.chat.helpers({
    chatMessages: function(){
      return Messages.find({});
    }
  });

  Tracker.autorun(function (){
    mySub = Meteor.subscribe('messages');
  });
}
like image 992
Miriam Avatar asked Dec 08 '25 21:12

Miriam


1 Answers

If Date() was a reactive datasource, it would work but it's not.

You can create a Timer at server side that will handle it. The best design I see id: pick the next message future date and set a Timer with the time difference and also get the next message time. Of course it's dependes on how your application works.

Read more about Timers in Meteor: https://docs.meteor.com/#/full/timers

like image 60
Mário Avatar answered Dec 11 '25 10:12

Mário



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!