Synchronized schedule expiration on Basic Schema

Having some trouble configuring a cron job using the percolate:synced-cron package to expire collection entries based on simple schema date and time fields. Wondering if there is an alternative approach or if something is incorrect in my setup?

Encountering this error:

TypeError: Posts.find(...).toArray is not a function

Synced Cron Code

SyncedCron.start();


SyncedCron.add({
  name: 'Expire Events',
  schedule: function(parser) {
    return parser.text('every 15 minutes');
  },
  job: function() {
    expireToday = Posts.find ({
      date: new Date().toISOString().substring(0,10)
    }).toArray();
    console.log(expireToday);
    for (i = 0; i < expireToday.length; i++) {
      expireId = expireToday.eq(i)._id;
      console.log(expireId);
      if (expireToday.eq(i).time < new Date().toTimeString().substring(0,5)) {
        Posts.deleteOne({_id : expireId});
      }
    }
  }
});

Simple Schema Coffee Code

Schemas.Posts = new SimpleSchema
    title:
        type:String
        max: 60
        optional: true

    content:
        type: String
        optional: true
        autoform:
            rows: 5

    createdAt:
        type: Date
        autoValue: ->
            if this.isInsert
                new Date()

    updatedAt:
        type:Date
        optional:true
        autoValue: ->
            if this.isUpdate
                new Date()


    time:
        type: String
        optional: false
        autoform:
            afFieldInput:
                type: 'time'


    date:
        type: String
        optional: false
        autoform:
            afFieldInput:
                type: 'date'


    owner:
        type: String
        regEx: SimpleSchema.RegEx.Id
        autoValue: ->
            if this.isInsert
                Meteor.userId()
        autoform:
            options: ->
                _.map Meteor.users.find().fetch(), (user)->
                    label: user.emails[0].address
                    value: user._id

Example mongo date and time

"date" : "2017-09-10"
"time" : "01:01"

Answer №1

The error message indicates that the following operation failed:

expireToday = Posts.find ({
  date: new Date().toISOString().substring(0,10)
}).toArray();

This suggests that the Posts.find() method did not yield any data that could be transformed into an array.

Since it returns a cursor, you might have intended to include a .fetch() to retrieve an array of objects instead?

In any scenario, it's important to verify the output of a function like this to ensure it is producing the expected results - adhering to fundamental defensive coding principles.

Answer №2

For more information, check out this related post

Converting dates to strings can hinder search operations in mongodb. To target documents that expire on the current day, it's essential to define "today" from midnight to midnight. Furthermore, performing bulk deletions is more efficient when executing server-side code (SyncedCron jobs are always executed on the server).

SyncedCron.add({
  name: 'Expire Events',
  schedule: function(parser) {
    return parser.text('every 15 minutes');
  },
  job: function() {
    let todayStart = new Date();
    todayStart.setHours(0,0,0,0);
    let todayEnd = todayStart.setHours(23,59,59,999);
    Posts.remove ({ date: {$gte: todayStart, $lte: todayEnd });
  }
});

However, this approach assumes datetime values are stored in mongodb datetime fields rather than as strings (which is recommended for proper timezone support).

If you prefer sticking with your schema where date and time are stored as strings, you can modify the implementation like so:

SyncedCron.add({
  name: 'Expire Events',
  schedule: function(parser) {
    return parser.text('every 15 minutes');
  },
  job: function() {
    let today = new Date().toISOString().substring(0,10);
    let now = new Date().toTimeString().substring(0,5);
    Posts.remove ({ date: today, time: { $lte: now });
  }
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to send information to the nested component's inner scope?

I am facing an issue with rendering a list of request/response pairs in my controller using components(directives). It appears that only string attributes are being passed to the component's scope, while objects are being ignored. You can view the f ...

Eliminate any div elements that do not contain tables

I am dealing with tables nested inside divs, and some of them are either empty, contain a single space, or have a single character like "-", which I refer to as EMPTY DIVs. What is the best way to use JavaScript to remove these EMPTY DIVs upon loading the ...

Suggestions for displaying images of varying resolutions in a circular format similar to Google's style

What is the best way to display dynamic images with varying resolutions in a circle like Google? I have tried using the Bootstrap class "img-circle", but it only works for images with a resolution of 304*236. If the image resolution is different, it appear ...

Reveal and conceal information with a customized web address

I have a PHP and MySQL blog that I want to display in a div using show and hide JavaScript functions. Everything works fine with other divs, but the issue arises when clicking on a vanity URL causing my webpage to refresh every time it's clicked. The ...

Ensuring the validity of a signed cookie in Node using Express

I'm currently working on incorporating signed cookies in Node's express module. I've reviewed the documentation, but I'm struggling to understand how to properly verify them. My understanding is that verification must occur on the serve ...

deleting the current product information during an ajax request

After executing the query provided below, I have $product_list in this code. However, I want to use ajax so that when I click on the button link1, $product_list gets emptied. How can I clear the content within products_list using an ajax call triggered by ...

How can I utilize Luxon to calculate the total number of days that are equal to or greater than 30?

Looking at my current array structure const arr = [ { id: '1', name: 'thing1', createdAt: '2022-09-21T16:26:02Z', }, { id: '2', name: 'thing1', createdAt: '2022-11-21T16:20:20Z', } ...

Is there a way for me to retrieve the variable from one function and use it in another

I have a tool for managing images with descriptions that allows me to edit both the text and the image file. The challenge is saving the modifications I make in my database. Currently, I can only save changes if I modify the image itself. If I only update ...

Utilizing a MONGO_URL to efficiently run multiple Meteor applications on a single server

I have successfully deployed a Meteor application on my Ubuntu server using Meteor Up (MUP) and everything is working well. However, when attempting to deploy a second app on the same server, I encounter issues with connecting to MongoDB. The error message ...

Is there a way to display a paragraph when a button is clicked?

I want my paragraph to appear when the button is clicked <button class="con-button" type="button">CLICK HERE</button> <p id="d-c" class="d-c">Thank you for reaching out to <strong&g ...

Using jQuery to toggle visibility based on data equivalence

I created a code snippet in which I am implementing jQuery show/hide functionality when the data attribute matches. Here is the HTML structure: <div class="container"> <div class="item" data-item="1">1 <div class="inside" data-c ...

How can I log an object definition and text in the same console.log statement?

Looking for a way to correctly display "obj" in the same string as "note." Here's my JavaScript code: console.log(obj);// [query: "wordOfTheDay"] console.log(note + " : " + obj ); // obj does not show up I want to ensure that "obj" displays properly ...

Issue with October CMS: Radio button selection triggers an Ajax call, but clicking twice in quick succession causes the content

I am currently utilizing October CMS and materializecss to develop a form with options on one of my pages. The form functions correctly as it dynamically loads content when different options are clicked. However, I have identified a problem where clicking ...

Steps for accessing an alternative schema within a virtual method

Looking to implement a virtual (get) method for my MongoDb collection, specifically the Parts collection. This method needs to access a different schema in order to check if a document is considered 'obsolete' based on a timestamp stored in anoth ...

I'm attempting to conceal a div five seconds after the page loads, but for some reason, it's not working. What could be the

Here is the snippet of code I'm working on: <div class="pop-up-chat"> <div id="div1"> <div class="pop-up-msg regular-text">Hi, how can I assist you?</div> <div class="tr ...

The customized uploading button functions seamlessly on desktop devices, yet encounters issues when used on

On my website, I have implemented a custom upload button alongside a hidden file input with the class .invisible-file-input. Here is how it is set up: Javascript $('.call-upload').click(function () { $(this).siblings('.invisible- ...

Unable to add a string to a http get request in Angular

When a specific ID is typed into the input field, it will be saved as searchText: <form class="input-group" ng-submit="getMainData()"> <input type="text" class="form-control" ng-model="searchText" placeholder=" Type KvK-nummer and Press Enter" ...

I need to confirm the existence of two columns, "name" and "group", in my database. If they are found, I want to display a message saying they already exist. If they are not found

How can I modify this HTML with AJAX to display a successful message and insert into the database, but also show an error message if the name already exists after validation? <form action="" id="manage-project"> <label for=&qu ...

Error: The function updateElement does not exist

Currently, I am facing an issue while trying to update an element in an array by adding an object as a property. This requires user interaction through a modal where the form is filled and then added as a property for a specific node. However, I encountere ...

Navigating the issue of "Experiencing additional hooks rendered compared to the previous render"

I'm currently in the process of developing a small application where certain elements will be nested within one another. My approach involves segmenting each component into its own file (children), returning a function with two components in each Rend ...