[SOLVED] Best method to create time related functions


#1

Hello guys,

I am a total newbie with Meteor, and I am loving it! I just need a hand in using the logic.
Currently, I’m working on a project that aims to reactivly change parts of the page based on what time it is.

The app, in short, is a bus-like timetable app that shows what state is the bus in at certain times. For example, at 7AM, the bus is on route, at 9AM, the bus is parked.

What I had in mind was create a collection for timetables, and one for buses, and link each timetable to its relevant bus.

a pseudocode might look something like this:
If SystemCurrentTime is 7AM,
look for 7AM in bus 1 timetable collection
Show Bus 1 State for that time
end if

I may be thinking in the wrong way here, which is why I need your assistance that I would eternally appreciate!
What is the best way to compare system times to collection variables, and how would be reactive? (shown on the screen real time).

Thank you so much!


#2

Hey there and welcome to the wonderful world of Meteor!

I don’t want to speak to the viability of your solution because 1) I don’t understand your problem as well as you do and 2) I feel trial and error is the best way to learn how something works.

BUT, here’s some relevant info that should help you on your journey.

If you have a collection of documents that looks like this:

{
  bus: 'A',
  state: 'Parked',
  startTime: 700,
  endTime: 800
}
{
  bus: 'A',
  state: 'On Route',
  startTime: 800,
  endTime: 930
}

and you want to find out what bus A is doing at a particular time of day (example, 7:45), you can find it with the query:

BusTimetables.findOne({
  bus: 'A',
  startTime: {
    $lte: 745 // start time is less than or equal to 745
  },
  endTime: {
    $gt: 745 // end time is greater than 745
  }
});

Note: This is a very simple example that doesn’t accommodate timezone differences. It’s just meant to illustrate how to query based on a range. You can do the same thing with dates.

Have you followed the Meteor tutorials? You’ll want to pay attention to Publications/Subscriptions for information about sending reactive data to the client.


#3

Thank you so much for getting back to me.

Yes, I haven’t drawn up the application just yet, and I am trying to figure out the logic beforehand.
I did start with tutorials and built a couple of apps based on tutorials I read/watched.

Your suggestion definitely makes sense and gives me few hints on how to engage.
How can I actively make my app reload itself to check for time and then compare it to bus.startTime() for example?


#4

Here’s the great thing about Meteor: you don’t have to reload the page in order to see changes in data. It’s referred to as reactivity. Certain data in Meteor is referred to as being reactive, such as a mongo cursor, or reactive variable.

Building off of the previous example, let’s make a publication on the server for our client to subscribe to:

Meteor.publish('busStateAtTime', function (busName, time) {
  return BusTimetables.find({
    bus: busName,
    startTime: {
      $lte: time
    },
    endTime: {
      $gt: time
    }
  });
});

On the client we’ll need to do two things, make a reactive variable to represent a time and subscribe to the publication so that we can get new information as the time changes.

Using reactive var, lets make the variable and update it every minute.

const whatTimeIsIt = new ReactiveVar();

// set interval lets you run a function every _____ milliseconds
Meteor.setInterval(() => {
  const h = (new Date()).getHours();                // hours
  const m = (new Date()).getMinutes();              // minutes
  const timeAsAString = `${h}${m}`;                 // convert to a string
  const timeAsANumber = parseInt(timeAsAString);    // convert to a number
  whatTimeIsIt.set(timeAsANumber);                  // update our reactive variable
}, 60 * 1000);                                      // 60 * 1000 = 60,000ms (1 minute)

Now that we have a reactive variable that is updated every minute, we want to use that to subscribe to the publication we created earlier. We will use Tracker so that our subscription updates each time our reactive variable updates.

Tracker.autorun(() => {
  Meteor.subscribe('busStateAtTime', 'A', whatTimeIsIt.get());
});

Then, when you want to access this document that represents the bus’s state, you can do so with:

BusTimetables.findOne({
  bus: 'A',
  startTime: {
    $lte: whatTimeIsIt.get()
  },
  endTime: {
    $gt: whatTimeIsIt.get()
  }
});

BusTimetables.findOne is also a reactive data-source, so depending on which frontend framework you choose, you’ll be able to ensure your UI updates as the bus timetable document changes.


#5

Oh man this is exactly what I was after! Thank you so much.