Home > OS >  Automate NodeJS Express Get and Post request using Cron
Automate NodeJS Express Get and Post request using Cron

Time:10-05

I have an existing get and post request from database which is:

router.post('/stackExample', async (req, res) => {
  try {

    //MAKE GET REQUEST FROM MONGODB
    const stackCron = await Borrower.aggregate([
      { $unwind: { path: "$application", preserveNullAndEmptyArrays: true } },
      {
        $project: {
          'branch': '$branch',
          'status': '$application.status',
        },
      },
      { $match: { status: 'Active' } },
    ]);      

//MAKE POST REQUEST TO MONGODB
    for (let k = 0; k < stackCron.length; k  ) {
      const branch = stackCron[k].branch;
      const status = stackCron[k].status;    
      const lrInterest = await Financial.updateOne({ accountName: 'Processing Fee Income'},
        {
          $push:
          {
            "transactions":
            {
              type: 'Credit',
              firstName: 'SysGen',
              lastName: 'SysGen2',
              amount: 100,
              date: new Date(),
            }
          }
        })
    }    

    res.json({ success: true, message: "Success" });
     } catch (err) { res.json({ success: false, message: 'An error occured' }); }

  });

This code works fine if request is made using the client but I want to automate this via cron:

Here is what I did:

var CronJob = require('cron').CronJob;
var job = new CronJob('* * * * * *', function () {

  makeRequest()

}, null, true, 'America/Los_Angeles');
job.start();



function makeRequest(message){
//Copy-paste entire router post request.    
}

There seems to be no response if I copy-paste my code in the function. What have I missed?

CodePudding user response:

  1. There is no response from a cron job because there is no request coming to your makeRequest function. That makes sense because a cron job is independent of any incoming requests.
  2. One other reason, you might not be getting any data from your updateOne operation is that it doesn't return the updated document. It returns the status of that operation instead. Take a look here. If you want to get the updated document you might want to use findOneAndUpdate.
const response = await Todo.findOneAndUpdate(
  { _id: "a1s2d3f4f4d3s2a1s2d3f4" },
  { title: "Get Groceries" },
  { new: true }
);
// response will have updated document
// We won't need this here. This is just to tell you how to get the updated document without making another database query explicitly
  1. The body of your router function is performing an async/await operation. But you didn't specify the makeRequest function to be async. This could also be the issue.
  2. cron job will update the database but if you want to get the updated documents, you'll have to make a GET call to the server and define a new route, with required parameters/query.

Your makeRequest function will look something like this

async function makeRequest() {
  try {
    //MAKE GET REQUEST FROM MONGODB
    const stackCron = await Borrower.aggregate([
      { $unwind: { path: "$application", preserveNullAndEmptyArrays: true } },
      {
        $project: {
          branch: "$branch",
          status: "$application.status",
        },
      },
      { $match: { status: "Active" } },
    ]);

    //MAKE POST REQUEST TO MONGODB
    for (let k = 0; k < stackCron.length; k  ) {
      const branch = stackCron[k].branch;
      const status = stackCron[k].status;
      const lrInterest = await Financial.updateOne(
        { accountName: "Processing Fee Income" },
        {
          $push: {
            transactions: {
              type: "Credit",
              firstName: "SysGen",
              lastName: "SysGen2",
              amount: 100,
              date: new Date(),
            },
          },
        }
      );
    }
    /**
     * Write to a log file if you want to keep the record of this operation
     */
  } catch (err) {
    /**
     * Similarly write the error to the same log file as well.
     */
  }
}

In your cron job

var job = new CronJob(
  "* * * * * *",
  async function () {
    await makeRequest();
  },
  null,
  true,
  "America/Los_Angeles"
);


Your new route

router.get("/stack/:accountName", async (req, res, next) => {
  const { accountName } = req.params;
  try {
    const financial = await Financial.find({ accountName });
    res.status(200).json({ message: "success", data: financial });
  } catch (err) {
    res.status(500).json({ message: "error", reason: err.message });
  }
});

Simply call it as

fetch(
  `http://example.net/stack/${encodeURIComponent("Processing Fee Income")}`,
  { method: "GET" }
);
  • Related