Issue
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?
Solution
- There is no response from a
cron
job because there is norequest
coming to yourmakeRequest
function. That makes sense because acron
job is independent of any incoming requests. - 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 usefindOneAndUpdate
.
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
- The body of your router function is performing an
async/await
operation. But you didn't specify themakeRequest
function to beasync
. This could also be the issue. cron
job will update the database but if you want to get the updated documents, you'll have to make aGET
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" }
);
Answered By - Hamza Asif